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

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

Issue 11125002: Add QuicFramer and friends. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix final comments. Created 8 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « net/quic/quic_framer.h ('k') | net/quic/quic_framer_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_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) {
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
OLDNEW
« no previous file with comments | « net/quic/quic_framer.h ('k') | net/quic/quic_framer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698