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) { | |
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 | |
OLD | NEW |