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

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

Powered by Google App Engine
This is Rietveld 408576698