OLD | NEW |
---|---|
(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_framer.h" | |
6 | |
7 #include "base/hash_tables.h" | |
8 #include "net/quic/crypto/quic_decrypter.h" | |
9 #include "net/quic/crypto/quic_encrypter.h" | |
10 #include "net/quic/quic_data_reader.h" | |
11 #include "net/quic/quic_data_writer.h" | |
12 #include "net/quic/quic_utils.h" | |
13 | |
14 using base::hash_set; | |
15 using base::StringPiece; | |
16 | |
17 namespace net { | |
18 | |
19 QuicFramer::QuicFramer(QuicDecrypter* decrypter, QuicEncrypter* encrypter) | |
20 : visitor_(NULL), | |
21 fec_builder_(NULL), | |
22 error_(QUIC_NO_ERROR), | |
23 decrypter_(decrypter), | |
24 encrypter_(encrypter) { | |
25 } | |
26 | |
27 QuicFramer::~QuicFramer() {} | |
28 | |
29 bool QuicFramer::ConstructFragementDataPacket( | |
30 const QuicPacketHeader& header, | |
31 const QuicFragments& fragments, | |
32 QuicPacket** packet) { | |
Ryan Sleevi
2012/10/17 04:27:13
Future point of consideration: https://sites.googl
| |
33 // Compute the length of the packet. We use "magic numbers" here because | |
34 // sizeof(member_) is not necessairly the same as sizeof(member_wire_format). | |
35 size_t len = kPacketHeaderSize; | |
36 len += 1; // fragment count | |
37 for (size_t i = 0; i < fragments.size(); ++i) { | |
38 len += 1; // space for the 8 bit type | |
39 len += ComputeFragmentPayloadLength(fragments[i]); | |
40 } | |
41 | |
42 QuicDataWriter writer(len); | |
43 | |
44 if (!WritePacketHeader(header, &writer)) { | |
45 return false; | |
46 } | |
47 | |
48 // fragment count | |
49 DCHECK_GE(256u, fragments.size()); | |
50 if (!writer.WriteUInt8(fragments.size())) { | |
51 return false; | |
52 } | |
53 | |
54 for (size_t i = 0; i < fragments.size(); ++i) { | |
55 const QuicFragment& fragment = fragments[i]; | |
56 if (!writer.WriteUInt8(fragment.type)) { | |
57 return false; | |
58 } | |
59 | |
60 switch (fragment.type) { | |
61 case STREAM_FRAGMENT: | |
62 if (!AppendStreamFragmentPayload(*fragment.stream_fragment, | |
63 &writer)) { | |
64 return false; | |
65 } | |
66 break; | |
67 case PDU_FRAGMENT: | |
68 return RaiseError(QUIC_INVALID_FRAGMENT_DATA); | |
69 case ACK_FRAGMENT: | |
70 if (!AppendAckFragmentPayload(*fragment.ack_fragment, &writer)) { | |
71 return false; | |
72 } | |
73 break; | |
74 case RST_STREAM_FRAGMENT: | |
75 if (!AppendRstStreamFragmentPayload(*fragment.rst_stream_fragment, | |
76 &writer)) { | |
77 return false; | |
78 } | |
79 break; | |
80 case CONNECTION_CLOSE_FRAGMENT: | |
81 if (!AppendConnectionCloseFragmentPayload( | |
82 *fragment.connection_close_fragment, &writer)) { | |
83 return false; | |
84 } | |
85 break; | |
86 default: | |
87 return RaiseError(QUIC_INVALID_FRAGMENT_DATA); | |
88 } | |
89 } | |
90 | |
91 *packet = new QuicPacket(writer.take(), len, true); | |
92 if (fec_builder_) { | |
93 fec_builder_->OnBuiltFecProtectedPayload(header, | |
94 (*packet)->FecProtectedData()); | |
95 } | |
96 | |
97 return true; | |
98 } | |
99 | |
100 bool QuicFramer::ConstructFecPacket(const QuicPacketHeader& header, | |
101 const QuicFecData& fec, | |
102 QuicPacket** packet) { | |
103 // Compute the length of the packet. We use "magic numbers" here because | |
104 // sizeof(member_) is not necessairly the same as sizeof(member_wire_format). | |
105 size_t len = kPacketHeaderSize; | |
106 len += 6; // first protected packet sequence number | |
107 len += fec.redundancy.length(); | |
108 | |
109 QuicDataWriter writer(len); | |
110 | |
111 if (!WritePacketHeader(header, &writer)) { | |
112 return false; | |
113 } | |
114 | |
115 if (!writer.WriteUInt48(fec.first_protected_packet_sequence_number)) { | |
116 return false; | |
117 } | |
118 | |
119 if (!writer.WriteBytes(fec.redundancy.data(), fec.redundancy.length())) { | |
120 return false; | |
121 } | |
122 | |
123 *packet = new QuicPacket(writer.take(), len, true); | |
124 | |
125 return true; | |
126 } | |
127 | |
128 void QuicFramer::IncrementRetransmitCount(QuicPacket* packet) { | |
129 CHECK_GT(packet->length(), kPacketHeaderSize); | |
130 | |
131 ++packet->mutable_data()[kRetransmissionOffset]; | |
132 } | |
133 | |
134 uint8 QuicFramer::GetRetransmitCount(QuicPacket* packet) { | |
135 CHECK_GT(packet->length(), kPacketHeaderSize); | |
136 | |
137 return packet->mutable_data()[kRetransmissionOffset]; | |
138 } | |
139 | |
140 bool QuicFramer::ProcessPacket(const IPEndPoint& peer_address, | |
141 const QuicEncryptedPacket& packet) { | |
142 DCHECK(!reader_.get()); | |
143 reader_.reset(new QuicDataReader(packet.data(), packet.length())); | |
144 visitor_->OnPacket(peer_address); | |
145 | |
146 // First parse the packet header. | |
147 QuicPacketHeader header; | |
148 if (!ProcessPacketHeader(&header, packet)) { | |
149 DLOG(WARNING) << "Unable to process header."; | |
150 return RaiseError(QUIC_INVALID_PACKET_HEADER); | |
151 } | |
152 | |
153 if (!visitor_->OnPacketHeader(header)) { | |
154 reader_.reset(NULL); | |
155 return true; | |
156 } | |
157 | |
158 if (packet.length() > kMaxPacketSize) { | |
159 DLOG(WARNING) << "Packet too large: " << packet.length(); | |
160 return RaiseError(QUIC_PACKET_TOO_LARGE); | |
161 } | |
162 | |
163 // Handle the payload. | |
164 if ((header.flags & PACKET_FLAGS_FEC) == 0) { | |
165 if (header.fec_group != 0) { | |
166 StringPiece payload = reader_->PeekRemainingPayload(); | |
167 visitor_->OnFecProtectedPayload(payload); | |
168 } | |
169 if (!ProcessFragmentData()) { | |
170 DLOG(WARNING) << "Unable to process fragment data."; | |
171 return false; | |
172 } | |
173 } else { | |
174 QuicFecData fec_data; | |
175 fec_data.fec_group = header.fec_group; | |
176 if (!reader_->ReadUInt48( | |
177 &fec_data.first_protected_packet_sequence_number)) { | |
178 set_detailed_error("Unable to read first protected packet."); | |
179 return false; | |
180 } | |
181 | |
182 fec_data.redundancy = reader_->ReadRemainingPayload(); | |
183 visitor_->OnFecData(fec_data); | |
184 } | |
185 | |
186 visitor_->OnPacketComplete(); | |
187 reader_.reset(NULL); | |
188 return true; | |
189 } | |
190 | |
191 bool QuicFramer::ProcessRevivedPacket(const IPEndPoint& peer_address, | |
192 const QuicPacketHeader& header, | |
193 StringPiece payload) { | |
194 DCHECK(!reader_.get()); | |
195 | |
196 visitor_->OnPacket(peer_address); | |
197 | |
198 visitor_->OnPacketHeader(header); | |
199 | |
200 if (payload.length() > kMaxPacketSize) { | |
201 set_detailed_error("Revived packet too large."); | |
202 return RaiseError(QUIC_PACKET_TOO_LARGE); | |
203 } | |
204 | |
205 reader_.reset(new QuicDataReader(payload.data(), payload.length())); | |
206 if (!ProcessFragmentData()) { | |
207 DLOG(WARNING) << "Unable to process fragment data."; | |
208 return false; | |
209 } | |
210 | |
211 visitor_->OnPacketComplete(); | |
212 reader_.reset(NULL); | |
213 return true; | |
214 } | |
215 | |
216 bool QuicFramer::WritePacketHeader(const QuicPacketHeader& header, | |
217 QuicDataWriter* writer) { | |
218 // ConnectionHeader | |
219 if (!writer->WriteUInt64(header.guid)) { | |
220 return false; | |
221 } | |
222 | |
223 if (!writer->WriteUInt48(header.packet_sequence_number)) { | |
224 return false; | |
225 } | |
226 | |
227 if (!writer->WriteBytes(&header.retransmission_count, 1)) { | |
228 return false; | |
229 } | |
230 | |
231 // CongestionMonitoredHeader | |
232 if (!writer->WriteUInt64(header.transmission_time)) { | |
233 return false; | |
234 } | |
235 | |
236 uint8 flags = static_cast<uint8>(header.flags); | |
237 if (!writer->WriteBytes(&flags, 1)) { | |
238 return false; | |
239 } | |
240 | |
241 if (!writer->WriteBytes(&header.fec_group, 1)) { | |
242 return false; | |
243 } | |
244 | |
245 return true; | |
246 } | |
247 | |
248 bool QuicFramer::ProcessPacketHeader(QuicPacketHeader* header, | |
249 const QuicEncryptedPacket& packet) { | |
250 // ConnectionHeader | |
251 if (!reader_->ReadUInt64(&header->guid)) { | |
252 set_detailed_error("Unable to read GUID."); | |
253 return false; | |
254 } | |
255 | |
256 if (!reader_->ReadUInt48(&header->packet_sequence_number)) { | |
257 set_detailed_error("Unable to read sequence number."); | |
258 return false; | |
259 } | |
260 | |
261 if (!reader_->ReadBytes(&header->retransmission_count, 1)) { | |
262 set_detailed_error("Unable to read retransmission count."); | |
263 return false; | |
264 } | |
265 | |
266 // CongestionMonitoredHeader | |
267 if (!reader_->ReadUInt64(&header->transmission_time)) { | |
268 set_detailed_error("Unable to read transmission time."); | |
269 return false; | |
270 } | |
271 | |
272 unsigned char flags; | |
273 if (!reader_->ReadBytes(&flags, 1)) { | |
274 set_detailed_error("Unable to read flags."); | |
275 return false; | |
276 } | |
277 | |
278 if (flags > PACKET_FLAGS_MAX) { | |
279 set_detailed_error("Illegal flags value."); | |
280 return false; | |
281 } | |
282 | |
283 header->flags = static_cast<QuicPacketFlags>(flags); | |
284 | |
285 if (!DecryptPayload(packet)) { | |
286 DLOG(WARNING) << "Unable to decrypt payload."; | |
287 return RaiseError(QUIC_DECRYPTION_FAILURE); | |
288 } | |
289 | |
290 if (!reader_->ReadBytes(&header->fec_group, 1)) { | |
291 set_detailed_error("Unable to read fec group."); | |
292 return false; | |
293 } | |
294 | |
295 return true; | |
296 } | |
297 | |
298 bool QuicFramer::ProcessFragmentData() { | |
299 uint8 fragment_count; | |
300 if (!reader_->ReadBytes(&fragment_count, 1)) { | |
301 set_detailed_error("Unable to read fragment count."); | |
302 return RaiseError(QUIC_INVALID_FRAGMENT_DATA); | |
303 } | |
304 | |
305 for (uint8 i = 0; i < fragment_count; ++i) { | |
306 uint8 fragment_type; | |
307 if (!reader_->ReadBytes(&fragment_type, 1)) { | |
308 set_detailed_error("Unable to read fragment type."); | |
309 return RaiseError(QUIC_INVALID_FRAGMENT_DATA); | |
310 } | |
311 switch (fragment_type) { | |
312 case STREAM_FRAGMENT: | |
313 if (!ProcessStreamFragment()) { | |
314 return RaiseError(QUIC_INVALID_FRAGMENT_DATA); | |
315 } | |
316 break; | |
317 case PDU_FRAGMENT: | |
318 if (!ProcessPDUFragment()) { | |
319 return RaiseError(QUIC_INVALID_FRAGMENT_DATA); | |
320 } | |
321 break; | |
322 case ACK_FRAGMENT: { | |
323 QuicAckFragment fragment; | |
324 if (!ProcessAckFragment(&fragment)) { | |
325 return RaiseError(QUIC_INVALID_FRAGMENT_DATA); | |
326 } | |
327 break; | |
328 } | |
329 case RST_STREAM_FRAGMENT: | |
330 if (!ProcessRstStreamFragment()) { | |
331 return RaiseError(QUIC_INVALID_RST_STREAM_DATA); | |
332 } | |
333 break; | |
334 case CONNECTION_CLOSE_FRAGMENT: | |
335 if (!ProcessConnectionCloseFragment()) { | |
336 return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA); | |
337 } | |
338 break; | |
339 default: | |
340 set_detailed_error("Illegal fragment type."); | |
341 DLOG(WARNING) << "Illegal fragment type: " << (int)fragment_type; | |
342 return RaiseError(QUIC_INVALID_FRAGMENT_DATA); | |
343 } | |
344 } | |
345 | |
346 return true; | |
347 } | |
348 | |
349 bool QuicFramer::ProcessStreamFragment() { | |
350 QuicStreamFragment fragment; | |
351 if (!reader_->ReadUInt32(&fragment.stream_id)) { | |
352 set_detailed_error("Unable to read stream_id."); | |
353 return false; | |
354 } | |
355 | |
356 uint8 fin; | |
357 if (!reader_->ReadBytes(&fin, 1)) { | |
358 set_detailed_error("Unable to read fin."); | |
359 return false; | |
360 } | |
361 if (fin > 1) { | |
362 set_detailed_error("Invalid fin value."); | |
363 return false; | |
364 } | |
365 fragment.fin = (fin == 1); | |
366 | |
367 if (!reader_->ReadUInt64(&fragment.offset)) { | |
368 set_detailed_error("Unable to read offset."); | |
369 return false; | |
370 } | |
371 | |
372 if (!reader_->ReadStringPiece16(&fragment.data)) { | |
373 set_detailed_error("Unable to read fragment data."); | |
374 return false; | |
375 } | |
376 | |
377 visitor_->OnStreamFragment(fragment); | |
378 return true; | |
379 } | |
380 | |
381 bool QuicFramer::ProcessPDUFragment() { | |
382 return false; | |
383 } | |
384 | |
385 bool QuicFramer::ProcessAckFragment(QuicAckFragment* fragment) { | |
386 if (!reader_->ReadUInt48(&fragment->received_info.largest_received)) { | |
387 set_detailed_error("Unable to read largest received."); | |
388 return false; | |
389 } | |
390 | |
391 if (!reader_->ReadUInt64(&fragment->received_info.time_received)) { | |
392 set_detailed_error("Unable to read time received."); | |
393 return false; | |
394 } | |
395 | |
396 uint8 num_unacked_packets; | |
397 if (!reader_->ReadBytes(&num_unacked_packets, 1)) { | |
398 set_detailed_error("Unable to read num unacked packets."); | |
399 return false; | |
400 } | |
401 | |
402 for (int i = 0; i < num_unacked_packets; ++i) { | |
403 QuicPacketSequenceNumber sequence_number; | |
404 if (!reader_->ReadUInt48(&sequence_number)) { | |
405 set_detailed_error("Unable to read sequence number in unacked packets."); | |
406 return false; | |
407 } | |
408 fragment->received_info.missing_packets.insert(sequence_number); | |
409 } | |
410 | |
411 if (!reader_->ReadUInt48(&fragment->sent_info.least_unacked)) { | |
412 set_detailed_error("Unable to read least unacked."); | |
413 return false; | |
414 } | |
415 | |
416 uint8 num_non_retransmiting_packets; | |
417 if (!reader_->ReadBytes(&num_non_retransmiting_packets, 1)) { | |
418 set_detailed_error("Unable to read num non-retransmitting."); | |
419 return false; | |
420 } | |
421 for (uint8 i = 0; i < num_non_retransmiting_packets; ++i) { | |
422 QuicPacketSequenceNumber sequence_number; | |
423 if (!reader_->ReadUInt48(&sequence_number)) { | |
424 set_detailed_error( | |
425 "Unable to read sequence number in non-retransmitting."); | |
426 return false; | |
427 } | |
428 fragment->sent_info.non_retransmiting.insert(sequence_number); | |
429 } | |
430 | |
431 uint8 congestion_info_type; | |
432 if (!reader_->ReadBytes(&congestion_info_type, 1)) { | |
433 set_detailed_error("Unable to read congestion info type."); | |
434 return false; | |
435 } | |
436 fragment->congestion_info.type = | |
437 static_cast<CongestionFeedbackType>(congestion_info_type); | |
438 | |
439 switch (fragment->congestion_info.type) { | |
440 case kNone: | |
441 break; | |
442 case kInterArrival: { | |
443 CongestionFeedbackMessageInterArrival* inter_arrival = | |
444 &fragment->congestion_info.inter_arrival; | |
445 if (!reader_->ReadUInt16( | |
446 &inter_arrival->accumulated_number_of_lost_packets)) { | |
447 set_detailed_error( | |
448 "Unable to read accumulated number of lost packets."); | |
449 return false; | |
450 } | |
451 if (!reader_->ReadBytes(&inter_arrival->offset_time, 2)) { | |
452 set_detailed_error("Unable to read offset time."); | |
453 return false; | |
454 } | |
455 if (!reader_->ReadUInt16(&inter_arrival->delta_time)) { | |
456 set_detailed_error("Unable to read delta time."); | |
457 return false; | |
458 } | |
459 break; | |
460 } | |
461 case kFixRate: { | |
462 CongestionFeedbackMessageFixRate* fix_rate = | |
463 &fragment->congestion_info.fix_rate; | |
464 if (!reader_->ReadUInt32(&fix_rate->bitrate_in_bytes_per_second)) { | |
465 set_detailed_error("Unable to read bitrate."); | |
466 return false; | |
467 } | |
468 break; | |
469 } | |
470 case kTCP: { | |
471 CongestionFeedbackMessageTCP* tcp = &fragment->congestion_info.tcp; | |
472 if (!reader_->ReadUInt16(&tcp->accumulated_number_of_lost_packets)) { | |
473 set_detailed_error( | |
474 "Unable to read accumulated number of lost packets."); | |
475 return false; | |
476 } | |
477 if (!reader_->ReadUInt16(&tcp->receive_window)) { | |
478 set_detailed_error("Unable to read receive window."); | |
479 return false; | |
480 } | |
481 break; | |
482 } | |
483 default: | |
484 set_detailed_error("Illegal congestion info type."); | |
485 DLOG(WARNING) << "Illegal congestion info type: " | |
486 << fragment->congestion_info.type; | |
487 return RaiseError(QUIC_INVALID_FRAGMENT_DATA); | |
488 } | |
489 | |
490 visitor_->OnAckFragment(*fragment); | |
491 return true; | |
492 } | |
493 | |
494 bool QuicFramer::ProcessRstStreamFragment() { | |
495 QuicRstStreamFragment fragment; | |
496 if (!reader_->ReadUInt32(&fragment.stream_id)) { | |
497 set_detailed_error("Unable to read stream_id."); | |
498 return false; | |
499 } | |
500 | |
501 if (!reader_->ReadUInt64(&fragment.offset)) { | |
502 set_detailed_error("Unable to read offset in rst fragment."); | |
503 return false; | |
504 } | |
505 | |
506 uint32 details; | |
507 if (!reader_->ReadUInt32(&details)) { | |
508 set_detailed_error("Unable to read rst stream details."); | |
509 return false; | |
510 } | |
511 fragment.details = static_cast<QuicErrorCode>(details); | |
512 | |
513 visitor_->OnRstStreamFragment(fragment); | |
514 return true; | |
515 } | |
516 | |
517 bool QuicFramer::ProcessConnectionCloseFragment() { | |
518 QuicConnectionCloseFragment fragment; | |
519 | |
520 uint32 details; | |
521 if (!reader_->ReadUInt32(&details)) { | |
522 set_detailed_error("Unable to read connection close details."); | |
523 return false; | |
524 } | |
525 fragment.details = static_cast<QuicErrorCode>(details); | |
526 | |
527 if (!ProcessAckFragment(&fragment.ack_fragment)) { | |
528 DLOG(WARNING) << "Unable to process ack fragment."; | |
529 return false; | |
530 } | |
531 | |
532 visitor_->OnConnectionCloseFragment(fragment); | |
533 return true; | |
534 } | |
535 | |
536 void QuicFramer::WriteTransmissionTime(QuicTransmissionTime time, | |
537 QuicPacket* packet) { | |
538 QuicDataWriter::WriteUint64ToBuffer( | |
539 time, packet->mutable_data() + kTransmissionTimeOffset); | |
540 } | |
541 | |
542 QuicEncryptedPacket* QuicFramer::EncryptPacket(const QuicPacket& packet) { | |
543 scoped_ptr<QuicData> out(encrypter_->Encrypt(packet.AssociatedData(), | |
544 packet.Plaintext())); | |
545 if (out.get() == NULL) { | |
546 RaiseError(QUIC_ENCRYPTION_FAILURE); | |
547 return NULL; | |
548 } | |
549 size_t len = kStartOfEncryptedData + out->length(); | |
550 char* buffer = new char[len]; | |
551 // TODO(rch): eliminate this buffer copy by passing in a buffer to Encrypt(). | |
552 memcpy(buffer, packet.data(), kStartOfEncryptedData); | |
553 memcpy(buffer + kStartOfEncryptedData, out->data(), out->length()); | |
554 return new QuicEncryptedPacket(buffer, len, true); | |
555 } | |
556 | |
557 size_t QuicFramer::GetMaxPlaintextSize(size_t ciphertext_size) { | |
558 return encrypter_->GetMaxPlaintextSize(ciphertext_size); | |
559 } | |
560 | |
561 bool QuicFramer::DecryptPayload(const QuicEncryptedPacket& packet) { | |
562 StringPiece encrypted; | |
563 if (!reader_->ReadStringPiece(&encrypted, reader_->BytesRemaining())) { | |
564 return false; | |
565 } | |
566 DCHECK(decrypter_.get() != NULL); | |
567 decrypted_.reset(decrypter_->Decrypt(packet.AssociatedData(), encrypted)); | |
568 if (decrypted_.get() == NULL) { | |
569 return false; | |
570 } | |
571 | |
572 reader_.reset(new QuicDataReader(decrypted_->data(), decrypted_->length())); | |
573 return true; | |
574 } | |
575 | |
576 size_t QuicFramer::ComputeFragmentPayloadLength(const QuicFragment& fragment) { | |
577 size_t len = 0; | |
578 // We use "magic numbers" here because sizeof(member_) is not necessairly the | |
579 // same as sizeof(member_wire_format). | |
580 switch (fragment.type) { | |
581 case STREAM_FRAGMENT: | |
582 len += 4; // stream id | |
583 len += 1; // fin | |
584 len += 8; // offset | |
585 len += 2; // space for the 16 bit length | |
586 len += fragment.stream_fragment->data.size(); | |
587 break; | |
588 case PDU_FRAGMENT: | |
589 DLOG(INFO) << "PDU_FRAGMENT not yet supported"; | |
590 break; // Need to support this eventually :> | |
591 case ACK_FRAGMENT: { | |
592 const QuicAckFragment& ack = *fragment.ack_fragment; | |
593 len += 6; // largest received packet sequence number | |
594 len += 8; // time delta | |
595 len += 1; // num missing packets | |
596 len += 6 * ack.received_info.missing_packets.size(); | |
597 len += 6; // least packet sequence number awaiting an ack | |
598 len += 1; // num non retransmitting packets | |
599 len += 6 * ack.sent_info.non_retransmiting.size(); | |
600 len += 1; // congestion control type | |
601 switch (ack.congestion_info.type) { | |
602 case kNone: | |
603 break; | |
604 case kInterArrival: | |
605 len += 6; | |
606 break; | |
607 case kFixRate: | |
608 len += 4; | |
609 break; | |
610 case kTCP: | |
611 len += 4; | |
612 break; | |
613 default: | |
614 set_detailed_error("Illegal feedback type."); | |
615 DLOG(INFO) << "Illegal feedback type: " << ack.congestion_info.type; | |
616 break; | |
617 } | |
618 break; | |
619 } | |
620 case RST_STREAM_FRAGMENT: | |
621 len += 4; // stream id | |
622 len += 8; // offset | |
623 len += 4; // details | |
624 break; | |
625 case CONNECTION_CLOSE_FRAGMENT: | |
626 len += 4; // details | |
627 len += ComputeFragmentPayloadLength( | |
628 QuicFragment(&fragment.connection_close_fragment->ack_fragment)); | |
629 break; | |
630 default: | |
631 set_detailed_error("Illegal fragment type."); | |
632 DLOG(INFO) << "Illegal fragment type: " << fragment.type; | |
633 break; | |
634 } | |
635 return len; | |
636 } | |
637 | |
638 bool QuicFramer::AppendStreamFragmentPayload( | |
639 const QuicStreamFragment& fragment, | |
640 QuicDataWriter* writer) { | |
641 if (!writer->WriteUInt32(fragment.stream_id)) { | |
642 return false; | |
643 } | |
644 if (!writer->WriteUInt8(fragment.fin)) { | |
645 return false; | |
646 } | |
647 if (!writer->WriteUInt64(fragment.offset)) { | |
648 return false; | |
649 } | |
650 if (!writer->WriteUInt16(fragment.data.size())) { | |
651 return false; | |
652 } | |
653 if (!writer->WriteBytes(fragment.data.data(), | |
654 fragment.data.size())) { | |
655 return false; | |
656 } | |
657 return true; | |
658 } | |
659 | |
660 bool QuicFramer::AppendAckFragmentPayload( | |
661 const QuicAckFragment& fragment, | |
662 QuicDataWriter* writer) { | |
663 if (!writer->WriteUInt48(fragment.received_info.largest_received)) { | |
664 return false; | |
665 } | |
666 if (!writer->WriteUInt64(fragment.received_info.time_received)) { | |
667 return false; | |
668 } | |
669 | |
670 size_t num_unacked_packets = fragment.received_info.missing_packets.size(); | |
671 if (!writer->WriteBytes(&num_unacked_packets, 1)) { | |
672 return false; | |
673 } | |
674 | |
675 hash_set<QuicPacketSequenceNumber>::const_iterator it = | |
676 fragment.received_info.missing_packets.begin(); | |
677 for (; it != fragment.received_info.missing_packets.end(); ++it) { | |
678 if (!writer->WriteUInt48(*it)) { | |
679 return false; | |
680 } | |
681 } | |
682 | |
683 if (!writer->WriteUInt48(fragment.sent_info.least_unacked)) { | |
684 return false; | |
685 } | |
686 | |
687 size_t num_non_retransmiting_packets = | |
688 fragment.sent_info.non_retransmiting.size(); | |
689 if (!writer->WriteBytes(&num_non_retransmiting_packets, 1)) { | |
690 return false; | |
691 } | |
692 | |
693 it = fragment.sent_info.non_retransmiting.begin(); | |
694 while (it != fragment.sent_info.non_retransmiting.end()) { | |
695 if (!writer->WriteUInt48(*it)) { | |
696 return false; | |
697 } | |
698 ++it; | |
699 } | |
700 | |
701 if (!writer->WriteBytes(&fragment.congestion_info.type, 1)) { | |
702 return false; | |
703 } | |
704 | |
705 switch (fragment.congestion_info.type) { | |
706 case kNone: | |
707 break; | |
708 case kInterArrival: { | |
709 const CongestionFeedbackMessageInterArrival& inter_arrival = | |
710 fragment.congestion_info.inter_arrival; | |
711 if (!writer->WriteUInt16( | |
712 inter_arrival.accumulated_number_of_lost_packets)) { | |
713 return false; | |
714 } | |
715 if (!writer->WriteBytes(&inter_arrival.offset_time, 2)) { | |
716 return false; | |
717 } | |
718 if (!writer->WriteUInt16(inter_arrival.delta_time)) { | |
719 return false; | |
720 } | |
721 break; | |
722 } | |
723 case kFixRate: { | |
724 const CongestionFeedbackMessageFixRate& fix_rate = | |
725 fragment.congestion_info.fix_rate; | |
726 if (!writer->WriteUInt32(fix_rate.bitrate_in_bytes_per_second)) { | |
727 return false; | |
728 } | |
729 break; | |
730 } | |
731 case kTCP: { | |
732 const CongestionFeedbackMessageTCP& tcp = fragment.congestion_info.tcp; | |
733 if (!writer->WriteUInt16(tcp.accumulated_number_of_lost_packets)) { | |
734 return false; | |
735 } | |
736 if (!writer->WriteUInt16(tcp.receive_window)) { | |
737 return false; | |
738 } | |
739 break; | |
740 } | |
741 default: | |
742 return false; | |
743 } | |
744 | |
745 return true; | |
746 } | |
747 | |
748 bool QuicFramer::AppendRstStreamFragmentPayload( | |
749 const QuicRstStreamFragment& fragment, | |
750 QuicDataWriter* writer) { | |
751 if (!writer->WriteUInt32(fragment.stream_id)) { | |
752 return false; | |
753 } | |
754 if (!writer->WriteUInt64(fragment.offset)) { | |
755 return false; | |
756 } | |
757 | |
758 uint32 details = static_cast<uint32>(fragment.details); | |
759 if (!writer->WriteUInt32(details)) { | |
760 return false; | |
761 } | |
762 return true; | |
763 } | |
764 | |
765 bool QuicFramer::AppendConnectionCloseFragmentPayload( | |
766 const QuicConnectionCloseFragment& fragment, | |
767 QuicDataWriter* writer) { | |
768 uint32 details = static_cast<uint32>(fragment.details); | |
769 if (!writer->WriteUInt32(details)) { | |
770 return false; | |
771 } | |
772 AppendAckFragmentPayload(fragment.ack_fragment, writer); | |
773 return true; | |
774 } | |
775 | |
776 bool QuicFramer::RaiseError(QuicErrorCode error) { | |
777 DLOG(INFO) << detailed_error_; | |
778 set_error(error); | |
779 visitor_->OnError(this); | |
780 reader_.reset(NULL); | |
781 return false; | |
782 } | |
783 | |
784 } // namespace net | |
OLD | NEW |