OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/quic_framer.h" | 5 #include "net/quic/quic_framer.h" |
6 | 6 |
7 #include "base/containers/hash_tables.h" | 7 #include "base/containers/hash_tables.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "net/quic/crypto/crypto_framer.h" | 9 #include "net/quic/crypto/crypto_framer.h" |
10 #include "net/quic/crypto/crypto_handshake_message.h" | 10 #include "net/quic/crypto/crypto_handshake_message.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 // ResetStream : 0b 00000001 (0x01) | 55 // ResetStream : 0b 00000001 (0x01) |
56 // ConnectionClose : 0b 00000010 (0x02) | 56 // ConnectionClose : 0b 00000010 (0x02) |
57 // GoAway : 0b 00000011 (0x03) | 57 // GoAway : 0b 00000011 (0x03) |
58 // WindowUpdate : 0b 00000100 (0x04) | 58 // WindowUpdate : 0b 00000100 (0x04) |
59 // Blocked : 0b 00000101 (0x05) | 59 // Blocked : 0b 00000101 (0x05) |
60 // | 60 // |
61 // Special Frame Types encode both a Frame Type and corresponding flags | 61 // Special Frame Types encode both a Frame Type and corresponding flags |
62 // all in the Frame Type byte. Currently defined Special Frame Types are: | 62 // all in the Frame Type byte. Currently defined Special Frame Types are: |
63 // Stream : 0b 1xxxxxxx | 63 // Stream : 0b 1xxxxxxx |
64 // Ack : 0b 01xxxxxx | 64 // Ack : 0b 01xxxxxx |
65 // CongestionFeedback : 0b 001xxxxx | |
66 // | 65 // |
67 // Semantics of the flag bits above (the x bits) depends on the frame type. | 66 // Semantics of the flag bits above (the x bits) depends on the frame type. |
68 | 67 |
69 // Masks to determine if the frame type is a special use | 68 // Masks to determine if the frame type is a special use |
70 // and for specific special frame types. | 69 // and for specific special frame types. |
71 const uint8 kQuicFrameTypeSpecialMask = 0xE0; // 0b 11100000 | 70 const uint8 kQuicFrameTypeSpecialMask = 0xE0; // 0b 11100000 |
72 const uint8 kQuicFrameTypeStreamMask = 0x80; | 71 const uint8 kQuicFrameTypeStreamMask = 0x80; |
73 const uint8 kQuicFrameTypeAckMask = 0x40; | 72 const uint8 kQuicFrameTypeAckMask = 0x40; |
74 const uint8 kQuicFrameTypeCongestionFeedbackMask = 0x20; | |
75 | 73 |
76 // Stream frame relative shifts and masks for interpreting the stream flags. | 74 // Stream frame relative shifts and masks for interpreting the stream flags. |
77 // StreamID may be 1, 2, 3, or 4 bytes. | 75 // StreamID may be 1, 2, 3, or 4 bytes. |
78 const uint8 kQuicStreamIdShift = 2; | 76 const uint8 kQuicStreamIdShift = 2; |
79 const uint8 kQuicStreamIDLengthMask = 0x03; | 77 const uint8 kQuicStreamIDLengthMask = 0x03; |
80 | 78 |
81 // Offset may be 0, 2, 3, 4, 5, 6, 7, 8 bytes. | 79 // Offset may be 0, 2, 3, 4, 5, 6, 7, 8 bytes. |
82 const uint8 kQuicStreamOffsetShift = 3; | 80 const uint8 kQuicStreamOffsetShift = 3; |
83 const uint8 kQuicStreamOffsetMask = 0x07; | 81 const uint8 kQuicStreamOffsetMask = 0x07; |
84 | 82 |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 return kNoPacket; | 350 return kNoPacket; |
353 } | 351 } |
354 break; | 352 break; |
355 case ACK_FRAME: | 353 case ACK_FRAME: |
356 if (!AppendAckFrameAndTypeByte( | 354 if (!AppendAckFrameAndTypeByte( |
357 header, *frame.ack_frame, &writer)) { | 355 header, *frame.ack_frame, &writer)) { |
358 LOG(DFATAL) << "AppendAckFrameAndTypeByte failed"; | 356 LOG(DFATAL) << "AppendAckFrameAndTypeByte failed"; |
359 return kNoPacket; | 357 return kNoPacket; |
360 } | 358 } |
361 break; | 359 break; |
362 case CONGESTION_FEEDBACK_FRAME: | |
363 if (!AppendCongestionFeedbackFrame( | |
364 *frame.congestion_feedback_frame, &writer)) { | |
365 LOG(DFATAL) << "AppendCongestionFeedbackFrame failed"; | |
366 return kNoPacket; | |
367 } | |
368 break; | |
369 case STOP_WAITING_FRAME: | 360 case STOP_WAITING_FRAME: |
370 if (!AppendStopWaitingFrame( | 361 if (!AppendStopWaitingFrame( |
371 header, *frame.stop_waiting_frame, &writer)) { | 362 header, *frame.stop_waiting_frame, &writer)) { |
372 LOG(DFATAL) << "AppendStopWaitingFrame failed"; | 363 LOG(DFATAL) << "AppendStopWaitingFrame failed"; |
373 return kNoPacket; | 364 return kNoPacket; |
374 } | 365 } |
375 break; | 366 break; |
376 case PING_FRAME: | 367 case PING_FRAME: |
377 // Ping has no payload. | 368 // Ping has no payload. |
378 break; | 369 break; |
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1117 return RaiseError(QUIC_INVALID_ACK_DATA); | 1108 return RaiseError(QUIC_INVALID_ACK_DATA); |
1118 } | 1109 } |
1119 if (!visitor_->OnAckFrame(frame)) { | 1110 if (!visitor_->OnAckFrame(frame)) { |
1120 DVLOG(1) << "Visitor asked to stop further processing."; | 1111 DVLOG(1) << "Visitor asked to stop further processing."; |
1121 // Returning true since there was no parsing error. | 1112 // Returning true since there was no parsing error. |
1122 return true; | 1113 return true; |
1123 } | 1114 } |
1124 continue; | 1115 continue; |
1125 } | 1116 } |
1126 | 1117 |
1127 // Congestion Feedback Frame | |
1128 if (frame_type & kQuicFrameTypeCongestionFeedbackMask) { | |
1129 if (quic_version_ > QUIC_VERSION_22) { | |
1130 set_detailed_error("Congestion Feedback Frame has been deprecated."); | |
1131 DLOG(WARNING) << "Congestion Feedback Frame has been deprecated."; | |
1132 } | |
1133 QuicCongestionFeedbackFrame frame; | |
1134 if (!ProcessCongestionFeedbackFrame(&frame)) { | |
1135 return RaiseError(QUIC_INVALID_CONGESTION_FEEDBACK_DATA); | |
1136 } | |
1137 if (!visitor_->OnCongestionFeedbackFrame(frame)) { | |
1138 DVLOG(1) << "Visitor asked to stop further processing."; | |
1139 // Returning true since there was no parsing error. | |
1140 return true; | |
1141 } | |
1142 continue; | |
1143 } | |
1144 | |
1145 // This was a special frame type that did not match any | 1118 // This was a special frame type that did not match any |
1146 // of the known ones. Error. | 1119 // of the known ones. Error. |
1147 set_detailed_error("Illegal frame type."); | 1120 set_detailed_error("Illegal frame type."); |
1148 DLOG(WARNING) << "Illegal frame type: " | 1121 DLOG(WARNING) << "Illegal frame type: " |
1149 << static_cast<int>(frame_type); | 1122 << static_cast<int>(frame_type); |
1150 return RaiseError(QUIC_INVALID_FRAME_DATA); | 1123 return RaiseError(QUIC_INVALID_FRAME_DATA); |
1151 } | 1124 } |
1152 | 1125 |
1153 switch (frame_type) { | 1126 switch (frame_type) { |
1154 case PADDING_FRAME: | 1127 case PADDING_FRAME: |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1399 return false; | 1372 return false; |
1400 } | 1373 } |
1401 | 1374 |
1402 ack_frame->revived_packets.insert(revived_packet); | 1375 ack_frame->revived_packets.insert(revived_packet); |
1403 } | 1376 } |
1404 | 1377 |
1405 return true; | 1378 return true; |
1406 } | 1379 } |
1407 | 1380 |
1408 bool QuicFramer::ProcessTimestampsInAckFrame(QuicAckFrame* ack_frame) { | 1381 bool QuicFramer::ProcessTimestampsInAckFrame(QuicAckFrame* ack_frame) { |
1409 if (version() > QUIC_VERSION_22 && !ack_frame->is_truncated) { | 1382 if (!ack_frame->is_truncated) { |
1410 uint8 num_received_packets; | 1383 uint8 num_received_packets; |
1411 if (!reader_->ReadBytes(&num_received_packets, 1)) { | 1384 if (!reader_->ReadBytes(&num_received_packets, 1)) { |
1412 set_detailed_error("Unable to read num received packets."); | 1385 set_detailed_error("Unable to read num received packets."); |
1413 return false; | 1386 return false; |
1414 } | 1387 } |
1415 | 1388 |
1416 if (num_received_packets > 0) { | 1389 if (num_received_packets > 0) { |
1417 uint8 delta_from_largest_observed; | 1390 uint8 delta_from_largest_observed; |
1418 if (!reader_->ReadBytes(&delta_from_largest_observed, | 1391 if (!reader_->ReadBytes(&delta_from_largest_observed, |
1419 PACKET_1BYTE_SEQUENCE_NUMBER)) { | 1392 PACKET_1BYTE_SEQUENCE_NUMBER)) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1476 set_detailed_error("Unable to read least unacked delta."); | 1449 set_detailed_error("Unable to read least unacked delta."); |
1477 return false; | 1450 return false; |
1478 } | 1451 } |
1479 DCHECK_GE(header.packet_sequence_number, least_unacked_delta); | 1452 DCHECK_GE(header.packet_sequence_number, least_unacked_delta); |
1480 stop_waiting->least_unacked = | 1453 stop_waiting->least_unacked = |
1481 header.packet_sequence_number - least_unacked_delta; | 1454 header.packet_sequence_number - least_unacked_delta; |
1482 | 1455 |
1483 return true; | 1456 return true; |
1484 } | 1457 } |
1485 | 1458 |
1486 bool QuicFramer::ProcessCongestionFeedbackFrame( | |
1487 QuicCongestionFeedbackFrame* frame) { | |
1488 uint8 feedback_type; | |
1489 if (!reader_->ReadBytes(&feedback_type, 1)) { | |
1490 set_detailed_error("Unable to read congestion feedback type."); | |
1491 return false; | |
1492 } | |
1493 frame->type = | |
1494 static_cast<CongestionFeedbackType>(feedback_type); | |
1495 | |
1496 switch (frame->type) { | |
1497 case kTCP: { | |
1498 CongestionFeedbackMessageTCP* tcp = &frame->tcp; | |
1499 uint16 receive_window = 0; | |
1500 if (!reader_->ReadUInt16(&receive_window)) { | |
1501 set_detailed_error("Unable to read receive window."); | |
1502 return false; | |
1503 } | |
1504 // Simple bit packing, don't send the 4 least significant bits. | |
1505 tcp->receive_window = static_cast<QuicByteCount>(receive_window) << 4; | |
1506 break; | |
1507 } | |
1508 default: | |
1509 set_detailed_error("Illegal congestion feedback type."); | |
1510 DLOG(WARNING) << "Illegal congestion feedback type: " | |
1511 << frame->type; | |
1512 return RaiseError(QUIC_INVALID_FRAME_DATA); | |
1513 } | |
1514 | |
1515 return true; | |
1516 } | |
1517 | |
1518 bool QuicFramer::ProcessRstStreamFrame(QuicRstStreamFrame* frame) { | 1459 bool QuicFramer::ProcessRstStreamFrame(QuicRstStreamFrame* frame) { |
1519 if (!reader_->ReadUInt32(&frame->stream_id)) { | 1460 if (!reader_->ReadUInt32(&frame->stream_id)) { |
1520 set_detailed_error("Unable to read stream_id."); | 1461 set_detailed_error("Unable to read stream_id."); |
1521 return false; | 1462 return false; |
1522 } | 1463 } |
1523 | 1464 |
1524 if (!reader_->ReadUInt64(&frame->byte_offset)) { | 1465 if (!reader_->ReadUInt64(&frame->byte_offset)) { |
1525 set_detailed_error("Unable to read rst stream sent byte offset."); | 1466 set_detailed_error("Unable to read rst stream sent byte offset."); |
1526 return false; | 1467 return false; |
1527 } | 1468 } |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1782 if (!ack_info.nack_ranges.empty()) { | 1723 if (!ack_info.nack_ranges.empty()) { |
1783 ack_size += kNumberOfNackRangesSize + kNumberOfRevivedPacketsSize; | 1724 ack_size += kNumberOfNackRangesSize + kNumberOfRevivedPacketsSize; |
1784 ack_size += min(ack_info.nack_ranges.size(), kMaxNackRanges) * | 1725 ack_size += min(ack_info.nack_ranges.size(), kMaxNackRanges) * |
1785 (missing_sequence_number_length + PACKET_1BYTE_SEQUENCE_NUMBER); | 1726 (missing_sequence_number_length + PACKET_1BYTE_SEQUENCE_NUMBER); |
1786 ack_size += min(ack.revived_packets.size(), | 1727 ack_size += min(ack.revived_packets.size(), |
1787 kMaxRevivedPackets) * largest_observed_length; | 1728 kMaxRevivedPackets) * largest_observed_length; |
1788 } | 1729 } |
1789 | 1730 |
1790 // In version 23, if the ack will be truncated due to too many nack ranges, | 1731 // In version 23, if the ack will be truncated due to too many nack ranges, |
1791 // then do not include the number of timestamps (1 byte). | 1732 // then do not include the number of timestamps (1 byte). |
1792 if (version() > QUIC_VERSION_22 && | 1733 if (ack_info.nack_ranges.size() <= kMaxNackRanges) { |
1793 ack_info.nack_ranges.size() <= kMaxNackRanges) { | |
1794 // 1 byte for the number of timestamps. | 1734 // 1 byte for the number of timestamps. |
1795 ack_size += 1; | 1735 ack_size += 1; |
1796 if (ack.received_packet_times.size() > 0) { | 1736 if (ack.received_packet_times.size() > 0) { |
1797 // 1 byte for sequence number, 4 bytes for timestamp for the first | 1737 // 1 byte for sequence number, 4 bytes for timestamp for the first |
1798 // packet. | 1738 // packet. |
1799 ack_size += 5; | 1739 ack_size += 5; |
1800 | 1740 |
1801 // 1 byte for sequence number, 2 bytes for timestamp for the other | 1741 // 1 byte for sequence number, 2 bytes for timestamp for the other |
1802 // packets. | 1742 // packets. |
1803 ack_size += 3 * (ack.received_packet_times.size() - 1); | 1743 ack_size += 3 * (ack.received_packet_times.size() - 1); |
(...skipping 11 matching lines...) Expand all Loading... |
1815 switch (frame.type) { | 1755 switch (frame.type) { |
1816 case STREAM_FRAME: | 1756 case STREAM_FRAME: |
1817 return GetMinStreamFrameSize(frame.stream_frame->stream_id, | 1757 return GetMinStreamFrameSize(frame.stream_frame->stream_id, |
1818 frame.stream_frame->offset, | 1758 frame.stream_frame->offset, |
1819 last_frame_in_packet, | 1759 last_frame_in_packet, |
1820 is_in_fec_group) + | 1760 is_in_fec_group) + |
1821 frame.stream_frame->data.TotalBufferSize(); | 1761 frame.stream_frame->data.TotalBufferSize(); |
1822 case ACK_FRAME: { | 1762 case ACK_FRAME: { |
1823 return GetAckFrameSize(*frame.ack_frame, sequence_number_length); | 1763 return GetAckFrameSize(*frame.ack_frame, sequence_number_length); |
1824 } | 1764 } |
1825 case CONGESTION_FEEDBACK_FRAME: { | |
1826 size_t len = kQuicFrameTypeSize; | |
1827 const QuicCongestionFeedbackFrame& congestion_feedback = | |
1828 *frame.congestion_feedback_frame; | |
1829 len += 1; // Congestion feedback type. | |
1830 | |
1831 switch (congestion_feedback.type) { | |
1832 case kTCP: | |
1833 len += 2; // Receive window. | |
1834 break; | |
1835 default: | |
1836 set_detailed_error("Illegal feedback type."); | |
1837 DVLOG(1) << "Illegal feedback type: " << congestion_feedback.type; | |
1838 break; | |
1839 } | |
1840 return len; | |
1841 } | |
1842 case STOP_WAITING_FRAME: | 1765 case STOP_WAITING_FRAME: |
1843 return GetStopWaitingFrameSize(sequence_number_length); | 1766 return GetStopWaitingFrameSize(sequence_number_length); |
1844 case PING_FRAME: | 1767 case PING_FRAME: |
1845 // Ping has no payload. | 1768 // Ping has no payload. |
1846 return kQuicFrameTypeSize; | 1769 return kQuicFrameTypeSize; |
1847 case RST_STREAM_FRAME: | 1770 case RST_STREAM_FRAME: |
1848 return GetMinRstStreamFrameSize() + | 1771 return GetMinRstStreamFrameSize() + |
1849 frame.rst_stream_frame->error_details.size(); | 1772 frame.rst_stream_frame->error_details.size(); |
1850 case CONNECTION_CLOSE_FRAME: | 1773 case CONNECTION_CLOSE_FRAME: |
1851 return GetMinConnectionCloseFrameSize() + | 1774 return GetMinConnectionCloseFrameSize() + |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1893 } | 1816 } |
1894 | 1817 |
1895 // stream id 2 bits. | 1818 // stream id 2 bits. |
1896 type_byte <<= kQuicStreamIdShift; | 1819 type_byte <<= kQuicStreamIdShift; |
1897 type_byte |= GetStreamIdSize(frame.stream_frame->stream_id) - 1; | 1820 type_byte |= GetStreamIdSize(frame.stream_frame->stream_id) - 1; |
1898 type_byte |= kQuicFrameTypeStreamMask; // Set Stream Frame Type to 1. | 1821 type_byte |= kQuicFrameTypeStreamMask; // Set Stream Frame Type to 1. |
1899 break; | 1822 break; |
1900 } | 1823 } |
1901 case ACK_FRAME: | 1824 case ACK_FRAME: |
1902 return true; | 1825 return true; |
1903 case CONGESTION_FEEDBACK_FRAME: { | |
1904 // TODO(ianswett): Use extra 5 bits in the congestion feedback framing. | |
1905 type_byte = kQuicFrameTypeCongestionFeedbackMask; | |
1906 break; | |
1907 } | |
1908 default: | 1826 default: |
1909 type_byte = static_cast<uint8>(frame.type); | 1827 type_byte = static_cast<uint8>(frame.type); |
1910 break; | 1828 break; |
1911 } | 1829 } |
1912 | 1830 |
1913 return writer->WriteUInt8(type_byte); | 1831 return writer->WriteUInt8(type_byte); |
1914 } | 1832 } |
1915 | 1833 |
1916 // static | 1834 // static |
1917 bool QuicFramer::AppendPacketSequenceNumber( | 1835 bool QuicFramer::AppendPacketSequenceNumber( |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2057 DCHECK_LE(0u, frame.delta_time_largest_observed.ToMicroseconds()); | 1975 DCHECK_LE(0u, frame.delta_time_largest_observed.ToMicroseconds()); |
2058 delta_time_largest_observed_us = | 1976 delta_time_largest_observed_us = |
2059 frame.delta_time_largest_observed.ToMicroseconds(); | 1977 frame.delta_time_largest_observed.ToMicroseconds(); |
2060 } | 1978 } |
2061 | 1979 |
2062 if (!writer->WriteUFloat16(delta_time_largest_observed_us)) { | 1980 if (!writer->WriteUFloat16(delta_time_largest_observed_us)) { |
2063 return false; | 1981 return false; |
2064 } | 1982 } |
2065 | 1983 |
2066 // Timestamp goes at the end of the required fields. | 1984 // Timestamp goes at the end of the required fields. |
2067 if (version() > QUIC_VERSION_22 && !truncated) { | 1985 if (!truncated) { |
2068 if (!AppendTimestampToAckFrame(frame, writer)) { | 1986 if (!AppendTimestampToAckFrame(frame, writer)) { |
2069 return false; | 1987 return false; |
2070 } | 1988 } |
2071 } | 1989 } |
2072 | 1990 |
2073 if (ack_info.nack_ranges.empty()) { | 1991 if (ack_info.nack_ranges.empty()) { |
2074 return true; | 1992 return true; |
2075 } | 1993 } |
2076 | 1994 |
2077 const uint8 num_missing_ranges = | 1995 const uint8 num_missing_ranges = |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2116 LOG_IF(DFATAL, !ContainsKey(frame.missing_packets, *iter)); | 2034 LOG_IF(DFATAL, !ContainsKey(frame.missing_packets, *iter)); |
2117 if (!AppendPacketSequenceNumber(largest_observed_length, | 2035 if (!AppendPacketSequenceNumber(largest_observed_length, |
2118 *iter, writer)) { | 2036 *iter, writer)) { |
2119 return false; | 2037 return false; |
2120 } | 2038 } |
2121 } | 2039 } |
2122 | 2040 |
2123 return true; | 2041 return true; |
2124 } | 2042 } |
2125 | 2043 |
2126 bool QuicFramer::AppendCongestionFeedbackFrame( | |
2127 const QuicCongestionFeedbackFrame& frame, | |
2128 QuicDataWriter* writer) { | |
2129 if (!writer->WriteBytes(&frame.type, 1)) { | |
2130 return false; | |
2131 } | |
2132 | |
2133 switch (frame.type) { | |
2134 case kTCP: { | |
2135 const CongestionFeedbackMessageTCP& tcp = frame.tcp; | |
2136 DCHECK_LE(tcp.receive_window, 1u << 20); | |
2137 // Simple bit packing, don't send the 4 least significant bits. | |
2138 uint16 receive_window = static_cast<uint16>(tcp.receive_window >> 4); | |
2139 if (!writer->WriteUInt16(receive_window)) { | |
2140 return false; | |
2141 } | |
2142 break; | |
2143 } | |
2144 default: | |
2145 return false; | |
2146 } | |
2147 | |
2148 return true; | |
2149 } | |
2150 | |
2151 bool QuicFramer::AppendTimestampToAckFrame(const QuicAckFrame& frame, | 2044 bool QuicFramer::AppendTimestampToAckFrame(const QuicAckFrame& frame, |
2152 QuicDataWriter* writer) { | 2045 QuicDataWriter* writer) { |
2153 DCHECK_GE(version(), QUIC_VERSION_23); | 2046 DCHECK_GE(version(), QUIC_VERSION_23); |
2154 DCHECK_GE(numeric_limits<uint8>::max(), frame.received_packet_times.size()); | 2047 DCHECK_GE(numeric_limits<uint8>::max(), frame.received_packet_times.size()); |
2155 // num_received_packets is only 1 byte. | 2048 // num_received_packets is only 1 byte. |
2156 if (frame.received_packet_times.size() > numeric_limits<uint8>::max()) { | 2049 if (frame.received_packet_times.size() > numeric_limits<uint8>::max()) { |
2157 return false; | 2050 return false; |
2158 } | 2051 } |
2159 | 2052 |
2160 uint8 num_received_packets = frame.received_packet_times.size(); | 2053 uint8 num_received_packets = frame.received_packet_times.size(); |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2319 | 2212 |
2320 bool QuicFramer::RaiseError(QuicErrorCode error) { | 2213 bool QuicFramer::RaiseError(QuicErrorCode error) { |
2321 DVLOG(1) << "Error detail: " << detailed_error_; | 2214 DVLOG(1) << "Error detail: " << detailed_error_; |
2322 set_error(error); | 2215 set_error(error); |
2323 visitor_->OnError(this); | 2216 visitor_->OnError(this); |
2324 reader_.reset(nullptr); | 2217 reader_.reset(nullptr); |
2325 return false; | 2218 return false; |
2326 } | 2219 } |
2327 | 2220 |
2328 } // namespace net | 2221 } // namespace net |
OLD | NEW |