| 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 <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 // Assumes this is a stream with a single lone packet. | 259 // Assumes this is a stream with a single lone packet. |
| 260 QuicFramer::GetMinStreamFrameSize(1u, offset, true, is_in_fec_group); | 260 QuicFramer::GetMinStreamFrameSize(1u, offset, true, is_in_fec_group); |
| 261 } | 261 } |
| 262 | 262 |
| 263 size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id, | 263 size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id, |
| 264 const QuicIOVector& iov, | 264 const QuicIOVector& iov, |
| 265 size_t iov_offset, | 265 size_t iov_offset, |
| 266 QuicStreamOffset offset, | 266 QuicStreamOffset offset, |
| 267 bool fin, | 267 bool fin, |
| 268 QuicFrame* frame, | 268 QuicFrame* frame, |
| 269 scoped_ptr<char[]>* buffer) { | 269 UniqueStreamBuffer* buffer) { |
| 270 DCHECK_GT(max_packet_length_, | 270 DCHECK_GT(max_packet_length_, |
| 271 StreamFramePacketOverhead(connection_id_length_, kIncludeVersion, | 271 StreamFramePacketOverhead(connection_id_length_, kIncludeVersion, |
| 272 PACKET_6BYTE_PACKET_NUMBER, offset, | 272 PACKET_6BYTE_PACKET_NUMBER, offset, |
| 273 IN_FEC_GROUP)); | 273 IN_FEC_GROUP)); |
| 274 DCHECK(buffer); | 274 DCHECK(buffer); |
| 275 | 275 |
| 276 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec(); | 276 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec(); |
| 277 | 277 |
| 278 LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset)) | 278 LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset)) |
| 279 << "No room for Stream frame, BytesFree: " << BytesFree() | 279 << "No room for Stream frame, BytesFree: " << BytesFree() |
| 280 << " MinStreamFrameSize: " | 280 << " MinStreamFrameSize: " |
| 281 << QuicFramer::GetMinStreamFrameSize(id, offset, true, is_in_fec_group); | 281 << QuicFramer::GetMinStreamFrameSize(id, offset, true, is_in_fec_group); |
| 282 | 282 |
| 283 if (iov_offset == iov.total_length) { | 283 if (iov_offset == iov.total_length) { |
| 284 LOG_IF(DFATAL, !fin) | 284 LOG_IF(DFATAL, !fin) |
| 285 << "Creating a stream frame with no data or fin."; | 285 << "Creating a stream frame with no data or fin."; |
| 286 // Create a new packet for the fin, if necessary. | 286 // Create a new packet for the fin, if necessary. |
| 287 *frame = QuicFrame(new QuicStreamFrame(id, true, offset, StringPiece())); | 287 *frame = QuicFrame(new QuicStreamFrame(id, true, offset, StringPiece())); |
| 288 return 0; | 288 return 0; |
| 289 } | 289 } |
| 290 | 290 |
| 291 const size_t data_size = iov.total_length - iov_offset; | 291 const size_t data_size = iov.total_length - iov_offset; |
| 292 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize( | 292 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize( |
| 293 id, offset, /* last_frame_in_packet= */ true, is_in_fec_group); | 293 id, offset, /* last_frame_in_packet= */ true, is_in_fec_group); |
| 294 size_t bytes_consumed = min<size_t>(BytesFree() - min_frame_size, data_size); | 294 size_t bytes_consumed = min<size_t>(BytesFree() - min_frame_size, data_size); |
| 295 | 295 |
| 296 bool set_fin = fin && bytes_consumed == data_size; // Last frame. | 296 bool set_fin = fin && bytes_consumed == data_size; // Last frame. |
| 297 buffer->reset(new char[bytes_consumed]); | 297 *buffer = NewStreamBuffer(bytes_consumed); |
| 298 CopyToBuffer(iov, iov_offset, bytes_consumed, buffer->get()); | 298 CopyToBuffer(iov, iov_offset, bytes_consumed, buffer->get()); |
| 299 *frame = QuicFrame(new QuicStreamFrame( | 299 *frame = QuicFrame(new QuicStreamFrame( |
| 300 id, set_fin, offset, StringPiece(buffer->get(), bytes_consumed))); | 300 id, set_fin, offset, StringPiece(buffer->get(), bytes_consumed))); |
| 301 return bytes_consumed; | 301 return bytes_consumed; |
| 302 } | 302 } |
| 303 | 303 |
| 304 // static | 304 // static |
| 305 void QuicPacketCreator::CopyToBuffer(const QuicIOVector& iov, | 305 void QuicPacketCreator::CopyToBuffer(const QuicIOVector& iov, |
| 306 size_t iov_offset, | 306 size_t iov_offset, |
| 307 size_t length, | 307 size_t length, |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 should_fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP); | 410 should_fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP); |
| 411 return packet_size_; | 411 return packet_size_; |
| 412 } | 412 } |
| 413 | 413 |
| 414 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) { | 414 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) { |
| 415 return AddFrame(frame, | 415 return AddFrame(frame, |
| 416 /*save_retransmittable_frames=*/true, | 416 /*save_retransmittable_frames=*/true, |
| 417 /*needs_padding=*/false, nullptr); | 417 /*needs_padding=*/false, nullptr); |
| 418 } | 418 } |
| 419 | 419 |
| 420 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame, char* buffer) { | 420 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame, |
| 421 UniqueStreamBuffer buffer) { |
| 421 return AddFrame(frame, | 422 return AddFrame(frame, |
| 422 /*save_retransmittable_frames=*/true, | 423 /*save_retransmittable_frames=*/true, |
| 423 /*needs_padding=*/false, buffer); | 424 /*needs_padding=*/false, buffer.Pass()); |
| 424 } | 425 } |
| 425 | 426 |
| 426 bool QuicPacketCreator::AddPaddedSavedFrame(const QuicFrame& frame, | 427 bool QuicPacketCreator::AddPaddedSavedFrame(const QuicFrame& frame, |
| 427 char* buffer) { | 428 UniqueStreamBuffer buffer) { |
| 428 return AddFrame(frame, | 429 return AddFrame(frame, |
| 429 /*save_retransmittable_frames=*/true, | 430 /*save_retransmittable_frames=*/true, |
| 430 /*needs_padding=*/true, buffer); | 431 /*needs_padding=*/true, buffer.Pass()); |
| 431 } | 432 } |
| 432 | 433 |
| 433 SerializedPacket QuicPacketCreator::SerializePacket( | 434 SerializedPacket QuicPacketCreator::SerializePacket( |
| 434 char* encrypted_buffer, | 435 char* encrypted_buffer, |
| 435 size_t encrypted_buffer_len) { | 436 size_t encrypted_buffer_len) { |
| 436 DCHECK_LT(0u, encrypted_buffer_len); | 437 DCHECK_LT(0u, encrypted_buffer_len); |
| 437 LOG_IF(DFATAL, queued_frames_.empty()) | 438 LOG_IF(DFATAL, queued_frames_.empty()) |
| 438 << "Attempt to serialize empty packet"; | 439 << "Attempt to serialize empty packet"; |
| 439 DCHECK_GE(packet_number_ + 1, fec_group_number_); | 440 DCHECK_GE(packet_number_ + 1, fec_group_number_); |
| 440 QuicPacketHeader header; | 441 QuicPacketHeader header; |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 case MTU_DISCOVERY_FRAME: | 590 case MTU_DISCOVERY_FRAME: |
| 590 return false; | 591 return false; |
| 591 default: | 592 default: |
| 592 return true; | 593 return true; |
| 593 } | 594 } |
| 594 } | 595 } |
| 595 | 596 |
| 596 bool QuicPacketCreator::AddFrame(const QuicFrame& frame, | 597 bool QuicPacketCreator::AddFrame(const QuicFrame& frame, |
| 597 bool save_retransmittable_frames, | 598 bool save_retransmittable_frames, |
| 598 bool needs_padding, | 599 bool needs_padding, |
| 599 char* buffer) { | 600 UniqueStreamBuffer buffer) { |
| 600 DVLOG(1) << "Adding frame: " << frame; | 601 DVLOG(1) << "Adding frame: " << frame; |
| 601 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec(); | 602 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec(); |
| 602 | 603 |
| 603 size_t frame_len = framer_->GetSerializedFrameLength( | 604 size_t frame_len = framer_->GetSerializedFrameLength( |
| 604 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group, | 605 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group, |
| 605 packet_number_length_); | 606 packet_number_length_); |
| 606 if (frame_len == 0) { | 607 if (frame_len == 0) { |
| 607 return false; | 608 return false; |
| 608 } | 609 } |
| 609 DCHECK_LT(0u, packet_size_); | 610 DCHECK_LT(0u, packet_size_); |
| 610 packet_size_ += ExpansionOnNewFrame() + frame_len; | 611 packet_size_ += ExpansionOnNewFrame() + frame_len; |
| 611 | 612 |
| 612 if (save_retransmittable_frames && ShouldRetransmit(frame)) { | 613 if (save_retransmittable_frames && ShouldRetransmit(frame)) { |
| 613 if (queued_retransmittable_frames_.get() == nullptr) { | 614 if (queued_retransmittable_frames_.get() == nullptr) { |
| 614 queued_retransmittable_frames_.reset( | 615 queued_retransmittable_frames_.reset( |
| 615 new RetransmittableFrames(encryption_level_)); | 616 new RetransmittableFrames(encryption_level_)); |
| 616 } | 617 } |
| 617 queued_frames_.push_back( | 618 queued_frames_.push_back( |
| 618 queued_retransmittable_frames_->AddFrame(frame, buffer)); | 619 queued_retransmittable_frames_->AddFrame(frame, buffer.Pass())); |
| 619 } else { | 620 } else { |
| 620 queued_frames_.push_back(frame); | 621 queued_frames_.push_back(frame); |
| 621 } | 622 } |
| 622 | 623 |
| 623 if (needs_padding) { | 624 if (needs_padding) { |
| 624 needs_padding_ = true; | 625 needs_padding_ = true; |
| 625 } | 626 } |
| 626 | 627 |
| 627 return true; | 628 return true; |
| 628 } | 629 } |
| 629 | 630 |
| 630 void QuicPacketCreator::MaybeAddPadding() { | 631 void QuicPacketCreator::MaybeAddPadding() { |
| 631 if (!needs_padding_) { | 632 if (!needs_padding_) { |
| 632 return; | 633 return; |
| 633 } | 634 } |
| 634 | 635 |
| 635 if (BytesFree() == 0) { | 636 if (BytesFree() == 0) { |
| 636 // Don't pad full packets. | 637 // Don't pad full packets. |
| 637 return; | 638 return; |
| 638 } | 639 } |
| 639 | 640 |
| 640 QuicPaddingFrame padding; | 641 QuicPaddingFrame padding; |
| 641 bool success = AddFrame(QuicFrame(&padding), false, false, nullptr); | 642 bool success = AddFrame(QuicFrame(&padding), false, false, nullptr); |
| 642 DCHECK(success); | 643 DCHECK(success); |
| 643 } | 644 } |
| 644 | 645 |
| 645 } // namespace net | 646 } // namespace net |
| OLD | NEW |