blob: 6d696768612054ddf11534f737c0c347b1b58673 [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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_creator.h"
6
7#include "base/logging.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00008#include "net/quic/crypto/quic_random.h"
9#include "net/quic/quic_fec_group.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000010#include "net/quic/quic_utils.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000011
12using base::StringPiece;
13using std::make_pair;
14using std::min;
15using std::pair;
16using std::vector;
17
18namespace net {
19
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000020QuicPacketCreator::QuicPacketCreator(QuicGuid guid,
21 QuicFramer* framer,
22 QuicRandom* random_generator,
23 bool is_server)
Torne (Richard Coles)58218062012-11-14 11:43:16 +000024 : guid_(guid),
25 framer_(framer),
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000026 random_generator_(random_generator),
Torne (Richard Coles)58218062012-11-14 11:43:16 +000027 sequence_number_(0),
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000028 fec_group_number_(0),
29 is_server_(is_server),
30 send_version_in_packet_(!is_server),
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010031 packet_size_(GetPacketHeaderSize(options_.send_guid_length,
32 send_version_in_packet_,
33 options_.send_sequence_number_length,
34 NOT_IN_FEC_GROUP)) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000035 framer_->set_fec_builder(this);
36}
37
38QuicPacketCreator::~QuicPacketCreator() {
39}
40
41void QuicPacketCreator::OnBuiltFecProtectedPayload(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000042 const QuicPacketHeader& header, StringPiece payload) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000043 if (fec_group_.get()) {
44 fec_group_->Update(header, payload);
45 }
46}
47
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000048bool QuicPacketCreator::ShouldSendFec(bool force_close) const {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010049 return fec_group_.get() != NULL && fec_group_->NumReceivedPackets() > 0 &&
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000050 (force_close ||
51 fec_group_->NumReceivedPackets() >= options_.max_packets_per_fec_group);
52}
Torne (Richard Coles)58218062012-11-14 11:43:16 +000053
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000054void QuicPacketCreator::MaybeStartFEC() {
55 if (options_.max_packets_per_fec_group > 0 && fec_group_.get() == NULL) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010056 DCHECK(queued_frames_.empty());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000057 // Set the fec group number to the sequence number of the next packet.
58 fec_group_number_ = sequence_number() + 1;
59 fec_group_.reset(new QuicFecGroup());
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010060 packet_size_ = GetPacketHeaderSize(options_.send_guid_length,
61 send_version_in_packet_,
62 options_.send_sequence_number_length,
63 IN_FEC_GROUP);
64 DCHECK_LE(packet_size_, options_.max_packet_length);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000065 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000066}
67
68// Stops serializing version of the protocol in packets sent after this call.
69// A packet that is already open might send kQuicVersionSize bytes less than the
70// maximum packet size if we stop sending version before it is serialized.
71void QuicPacketCreator::StopSendingVersion() {
72 DCHECK(send_version_in_packet_);
73 send_version_in_packet_ = false;
74 if (packet_size_ > 0) {
75 DCHECK_LT(kQuicVersionSize, packet_size_);
76 packet_size_ -= kQuicVersionSize;
77 }
78}
79
Ben Murdoch2385ea32013-08-06 11:01:04 +010080bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
81 QuicStreamOffset offset) const {
82 return BytesFree() >
83 QuicFramer::GetMinStreamFrameSize(framer_->version(), id, offset, true);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000084}
85
86// static
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010087size_t QuicPacketCreator::StreamFramePacketOverhead(
Ben Murdoch2385ea32013-08-06 11:01:04 +010088 QuicVersion version,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010089 QuicGuidLength guid_length,
90 bool include_version,
91 QuicSequenceNumberLength sequence_number_length,
92 InFecGroup is_in_fec_group) {
93 return GetPacketHeaderSize(guid_length, include_version,
94 sequence_number_length, is_in_fec_group) +
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010095 // Assumes this is a stream with a single lone packet.
Ben Murdoch2385ea32013-08-06 11:01:04 +010096 QuicFramer::GetMinStreamFrameSize(version, 1u, 0u, true);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000097}
98
99size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
100 StringPiece data,
101 QuicStreamOffset offset,
102 bool fin,
103 QuicFrame* frame) {
104 DCHECK_GT(options_.max_packet_length,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100105 StreamFramePacketOverhead(
Ben Murdoch2385ea32013-08-06 11:01:04 +0100106 framer_->version(), PACKET_8BYTE_GUID, kIncludeVersion,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100107 PACKET_6BYTE_SEQUENCE_NUMBER, IN_FEC_GROUP));
Ben Murdoch2385ea32013-08-06 11:01:04 +0100108 DCHECK(HasRoomForStreamFrame(id, offset));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000109
110 const size_t free_bytes = BytesFree();
111 size_t bytes_consumed = 0;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000112
113 if (data.size() != 0) {
Ben Murdochbb1529c2013-08-08 10:24:53 +0100114 // When a STREAM frame is the last frame in a packet, it consumes two fewer
115 // bytes of framing overhead.
116 // Anytime more data is available than fits in with the extra two bytes,
117 // the frame will be the last, and up to two extra bytes are consumed.
118 // TODO(ianswett): If QUIC pads, the 1 byte PADDING frame does not fit when
119 // 1 byte is available, because then the STREAM frame isn't the last.
120
121 // The minimum frame size(0 bytes of data) if it's not the last frame.
122 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
123 framer_->version(), id, offset, false);
124 // Check if it's the last frame in the packet.
125 if (data.size() + min_frame_size > free_bytes) {
126 // The minimum frame size(0 bytes of data) if it is the last frame.
127 size_t min_last_frame_size = QuicFramer::GetMinStreamFrameSize(
128 framer_->version(), id, offset, true);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100129 bytes_consumed =
Ben Murdochbb1529c2013-08-08 10:24:53 +0100130 min<size_t>(free_bytes - min_last_frame_size, data.size());
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100131 } else {
Ben Murdoch2385ea32013-08-06 11:01:04 +0100132 DCHECK_LT(data.size(), BytesFree());
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100133 bytes_consumed = data.size();
134 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000135
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000136 bool set_fin = fin && bytes_consumed == data.size(); // Last frame.
137 StringPiece data_frame(data.data(), bytes_consumed);
138 *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, data_frame));
139 } else {
140 DCHECK(fin);
141 // Create a new packet for the fin, if necessary.
142 *frame = QuicFrame(new QuicStreamFrame(id, true, offset, ""));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000143 }
144
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000145 return bytes_consumed;
146}
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000147
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000148SerializedPacket QuicPacketCreator::SerializeAllFrames(
149 const QuicFrames& frames) {
150 // TODO(satyamshekhar): Verify that this DCHECK won't fail. What about queued
151 // frames from SendStreamData()[send_stream_should_flush_ == false &&
152 // data.empty() == true] and retransmit due to RTO.
153 DCHECK_EQ(0u, queued_frames_.size());
154 for (size_t i = 0; i < frames.size(); ++i) {
155 bool success = AddFrame(frames[i], false);
156 DCHECK(success);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000157 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000158 SerializedPacket packet = SerializePacket();
159 DCHECK(packet.retransmittable_frames == NULL);
160 return packet;
161}
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000162
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000163bool QuicPacketCreator::HasPendingFrames() {
164 return !queued_frames_.empty();
165}
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000166
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000167size_t QuicPacketCreator::BytesFree() const {
168 const size_t max_plaintext_size =
169 framer_->GetMaxPlaintextSize(options_.max_packet_length);
170 if (packet_size_ > max_plaintext_size) {
171 return 0;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000172 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000173 return max_plaintext_size - packet_size_;
174}
175
176bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) {
177 return AddFrame(frame, true);
178}
179
180SerializedPacket QuicPacketCreator::SerializePacket() {
181 DCHECK_EQ(false, queued_frames_.empty());
182 QuicPacketHeader header;
183 FillPacketHeader(fec_group_number_, false, false, &header);
184
Ben Murdoch2385ea32013-08-06 11:01:04 +0100185 SerializedPacket serialized = framer_->BuildDataPacket(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000186 header, queued_frames_, packet_size_);
187 queued_frames_.clear();
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100188 packet_size_ = GetPacketHeaderSize(options_.send_guid_length,
189 send_version_in_packet_,
190 options_.send_sequence_number_length,
191 fec_group_.get() != NULL ?
192 IN_FEC_GROUP : NOT_IN_FEC_GROUP);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000193 serialized.retransmittable_frames = queued_retransmittable_frames_.release();
194 return serialized;
195}
196
197SerializedPacket QuicPacketCreator::SerializeFec() {
198 DCHECK_LT(0u, fec_group_->NumReceivedPackets());
199 DCHECK_EQ(0u, queued_frames_.size());
200 QuicPacketHeader header;
201 FillPacketHeader(fec_group_number_, true,
202 fec_group_->entropy_parity(), &header);
203 QuicFecData fec_data;
204 fec_data.fec_group = fec_group_->min_protected_packet();
205 fec_data.redundancy = fec_group_->payload_parity();
Ben Murdoch2385ea32013-08-06 11:01:04 +0100206 SerializedPacket serialized = framer_->BuildFecPacket(header, fec_data);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000207 fec_group_.reset(NULL);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000208 fec_group_number_ = 0;
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100209 // Reset packet_size_, since the next packet may not have an FEC group.
210 packet_size_ = GetPacketHeaderSize(options_.send_guid_length,
211 send_version_in_packet_,
212 options_.send_sequence_number_length,
213 NOT_IN_FEC_GROUP);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000214 DCHECK(serialized.packet);
215 DCHECK_GE(options_.max_packet_length, serialized.packet->length());
216 return serialized;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000217}
218
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000219SerializedPacket QuicPacketCreator::SerializeConnectionClose(
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000220 QuicConnectionCloseFrame* close_frame) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000221 QuicFrames frames;
222 frames.push_back(QuicFrame(close_frame));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000223 return SerializeAllFrames(frames);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000224}
225
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000226QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket(
Ben Murdoch558790d2013-07-30 15:19:42 +0100227 const QuicVersionVector& supported_versions) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100228 DCHECK(is_server_);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000229 QuicPacketPublicHeader header;
230 header.guid = guid_;
231 header.reset_flag = false;
232 header.version_flag = true;
233 header.versions = supported_versions;
234 QuicEncryptedPacket* encrypted =
Ben Murdoch2385ea32013-08-06 11:01:04 +0100235 framer_->BuildVersionNegotiationPacket(header, supported_versions);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000236 DCHECK(encrypted);
237 DCHECK_GE(options_.max_packet_length, encrypted->length());
238 return encrypted;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000239}
240
241void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000242 bool fec_flag,
243 bool fec_entropy_flag,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000244 QuicPacketHeader* header) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000245 header->public_header.guid = guid_;
246 header->public_header.reset_flag = false;
247 header->public_header.version_flag = send_version_in_packet_;
248 header->fec_flag = fec_flag;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000249 header->packet_sequence_number = ++sequence_number_;
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100250
251 bool entropy_flag;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000252 if (header->packet_sequence_number == 1) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100253 DCHECK(!fec_flag);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000254 // TODO(satyamshekhar): No entropy in the first message.
255 // For crypto tests to pass. Fix this by using deterministic QuicRandom.
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100256 entropy_flag = 0;
257 } else if (fec_flag) {
258 // FEC packets don't have an entropy of their own. Entropy flag for FEC
259 // packets is the XOR of entropy of previous packets.
260 entropy_flag = fec_entropy_flag;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000261 } else {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100262 entropy_flag = random_generator_->RandBool();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000263 }
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100264 header->entropy_flag = entropy_flag;
265 header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000266 header->fec_group = fec_group;
267}
268
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000269bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) {
270 return frame.type != ACK_FRAME && frame.type != CONGESTION_FEEDBACK_FRAME &&
271 frame.type != PADDING_FRAME;
272}
273
274bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
275 bool save_retransmittable_frames) {
276 size_t frame_len = framer_->GetSerializedFrameLength(
277 frame, BytesFree(), queued_frames_.empty());
278 if (frame_len == 0) {
279 return false;
280 }
281 packet_size_ += frame_len;
282
283 if (save_retransmittable_frames && ShouldRetransmit(frame)) {
284 if (queued_retransmittable_frames_.get() == NULL) {
285 queued_retransmittable_frames_.reset(new RetransmittableFrames());
286 }
287 if (frame.type == STREAM_FRAME) {
288 queued_frames_.push_back(
289 queued_retransmittable_frames_->AddStreamFrame(frame.stream_frame));
290 } else {
291 queued_frames_.push_back(
292 queued_retransmittable_frames_->AddNonStreamFrame(frame));
293 }
294 } else {
295 queued_frames_.push_back(frame);
296 }
297 return true;
298}
299
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000300} // namespace net