| 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 1400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1411 uint8 feedback_type; | 1411 uint8 feedback_type; |
| 1412 if (!reader_->ReadBytes(&feedback_type, 1)) { | 1412 if (!reader_->ReadBytes(&feedback_type, 1)) { |
| 1413 set_detailed_error("Unable to read congestion feedback type."); | 1413 set_detailed_error("Unable to read congestion feedback type."); |
| 1414 return false; | 1414 return false; |
| 1415 } | 1415 } |
| 1416 frame->type = | 1416 frame->type = |
| 1417 static_cast<CongestionFeedbackType>(feedback_type); | 1417 static_cast<CongestionFeedbackType>(feedback_type); |
| 1418 | 1418 |
| 1419 switch (frame->type) { | 1419 switch (frame->type) { |
| 1420 case kTimestamp: { | 1420 case kTimestamp: { |
| 1421 CongestionFeedbackMessageTimestamp* timestamp = &frame->timestamp; | 1421 set_detailed_error("Timestamp feedback not supported."); |
| 1422 uint8 num_received_packets; | 1422 return false; |
| 1423 if (!reader_->ReadBytes(&num_received_packets, 1)) { | |
| 1424 set_detailed_error("Unable to read num received packets."); | |
| 1425 return false; | |
| 1426 } | |
| 1427 | |
| 1428 if (num_received_packets > 0u) { | |
| 1429 uint64 smallest_received; | |
| 1430 if (!ProcessPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER, | |
| 1431 &smallest_received)) { | |
| 1432 set_detailed_error("Unable to read smallest received."); | |
| 1433 return false; | |
| 1434 } | |
| 1435 | |
| 1436 uint64 time_received_us; | |
| 1437 if (!reader_->ReadUInt64(&time_received_us)) { | |
| 1438 set_detailed_error("Unable to read time received."); | |
| 1439 return false; | |
| 1440 } | |
| 1441 QuicTime time_received = creation_time_.Add( | |
| 1442 QuicTime::Delta::FromMicroseconds(time_received_us)); | |
| 1443 | |
| 1444 timestamp->received_packet_times.insert( | |
| 1445 make_pair(smallest_received, time_received)); | |
| 1446 | |
| 1447 for (uint8 i = 0; i < num_received_packets - 1; ++i) { | |
| 1448 uint16 sequence_delta; | |
| 1449 if (!reader_->ReadUInt16(&sequence_delta)) { | |
| 1450 set_detailed_error( | |
| 1451 "Unable to read sequence delta in received packets."); | |
| 1452 return false; | |
| 1453 } | |
| 1454 | |
| 1455 int32 time_delta_us; | |
| 1456 if (!reader_->ReadBytes(&time_delta_us, sizeof(time_delta_us))) { | |
| 1457 set_detailed_error( | |
| 1458 "Unable to read time delta in received packets."); | |
| 1459 return false; | |
| 1460 } | |
| 1461 QuicPacketSequenceNumber packet = smallest_received + sequence_delta; | |
| 1462 timestamp->received_packet_times.insert( | |
| 1463 make_pair(packet, time_received.Add( | |
| 1464 QuicTime::Delta::FromMicroseconds(time_delta_us)))); | |
| 1465 } | |
| 1466 } | |
| 1467 break; | |
| 1468 } | 1423 } |
| 1469 case kTCP: { | 1424 case kTCP: { |
| 1470 CongestionFeedbackMessageTCP* tcp = &frame->tcp; | 1425 CongestionFeedbackMessageTCP* tcp = &frame->tcp; |
| 1471 uint16 receive_window = 0; | 1426 uint16 receive_window = 0; |
| 1472 if (!reader_->ReadUInt16(&receive_window)) { | 1427 if (!reader_->ReadUInt16(&receive_window)) { |
| 1473 set_detailed_error("Unable to read receive window."); | 1428 set_detailed_error("Unable to read receive window."); |
| 1474 return false; | 1429 return false; |
| 1475 } | 1430 } |
| 1476 // Simple bit packing, don't send the 4 least significant bits. | 1431 // Simple bit packing, don't send the 4 least significant bits. |
| 1477 tcp->receive_window = static_cast<QuicByteCount>(receive_window) << 4; | 1432 tcp->receive_window = static_cast<QuicByteCount>(receive_window) << 4; |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1780 return GetAckFrameSize(*frame.ack_frame, sequence_number_length); | 1735 return GetAckFrameSize(*frame.ack_frame, sequence_number_length); |
| 1781 } | 1736 } |
| 1782 case CONGESTION_FEEDBACK_FRAME: { | 1737 case CONGESTION_FEEDBACK_FRAME: { |
| 1783 size_t len = kQuicFrameTypeSize; | 1738 size_t len = kQuicFrameTypeSize; |
| 1784 const QuicCongestionFeedbackFrame& congestion_feedback = | 1739 const QuicCongestionFeedbackFrame& congestion_feedback = |
| 1785 *frame.congestion_feedback_frame; | 1740 *frame.congestion_feedback_frame; |
| 1786 len += 1; // Congestion feedback type. | 1741 len += 1; // Congestion feedback type. |
| 1787 | 1742 |
| 1788 switch (congestion_feedback.type) { | 1743 switch (congestion_feedback.type) { |
| 1789 case kTimestamp: { | 1744 case kTimestamp: { |
| 1790 const CongestionFeedbackMessageTimestamp& timestamp = | 1745 set_detailed_error("Timestamp feedback not supported."); |
| 1791 congestion_feedback.timestamp; | |
| 1792 len += 1; // Number received packets. | |
| 1793 if (!timestamp.received_packet_times.empty()) { | |
| 1794 len += PACKET_6BYTE_SEQUENCE_NUMBER; // Smallest received. | |
| 1795 len += 8; // Time. | |
| 1796 // 2 bytes per sequence number delta plus 4 bytes per delta time. | |
| 1797 len += PACKET_6BYTE_SEQUENCE_NUMBER * | |
| 1798 (timestamp.received_packet_times.size() - 1); | |
| 1799 } | |
| 1800 break; | 1746 break; |
| 1801 } | 1747 } |
| 1802 case kTCP: | 1748 case kTCP: |
| 1803 len += 2; // Receive window. | 1749 len += 2; // Receive window. |
| 1804 break; | 1750 break; |
| 1805 default: | 1751 default: |
| 1806 set_detailed_error("Illegal feedback type."); | 1752 set_detailed_error("Illegal feedback type."); |
| 1807 DVLOG(1) << "Illegal feedback type: " << congestion_feedback.type; | 1753 DVLOG(1) << "Illegal feedback type: " << congestion_feedback.type; |
| 1808 break; | 1754 break; |
| 1809 } | 1755 } |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2086 | 2032 |
| 2087 bool QuicFramer::AppendCongestionFeedbackFrame( | 2033 bool QuicFramer::AppendCongestionFeedbackFrame( |
| 2088 const QuicCongestionFeedbackFrame& frame, | 2034 const QuicCongestionFeedbackFrame& frame, |
| 2089 QuicDataWriter* writer) { | 2035 QuicDataWriter* writer) { |
| 2090 if (!writer->WriteBytes(&frame.type, 1)) { | 2036 if (!writer->WriteBytes(&frame.type, 1)) { |
| 2091 return false; | 2037 return false; |
| 2092 } | 2038 } |
| 2093 | 2039 |
| 2094 switch (frame.type) { | 2040 switch (frame.type) { |
| 2095 case kTimestamp: { | 2041 case kTimestamp: { |
| 2096 return AppendTimestampFrame(frame, writer); | 2042 // Timestamp feedback not supported. |
| 2043 return false; |
| 2097 } | 2044 } |
| 2098 case kTCP: { | 2045 case kTCP: { |
| 2099 const CongestionFeedbackMessageTCP& tcp = frame.tcp; | 2046 const CongestionFeedbackMessageTCP& tcp = frame.tcp; |
| 2100 DCHECK_LE(tcp.receive_window, 1u << 20); | 2047 DCHECK_LE(tcp.receive_window, 1u << 20); |
| 2101 // Simple bit packing, don't send the 4 least significant bits. | 2048 // Simple bit packing, don't send the 4 least significant bits. |
| 2102 uint16 receive_window = static_cast<uint16>(tcp.receive_window >> 4); | 2049 uint16 receive_window = static_cast<uint16>(tcp.receive_window >> 4); |
| 2103 if (!writer->WriteUInt16(receive_window)) { | 2050 if (!writer->WriteUInt16(receive_window)) { |
| 2104 return false; | 2051 return false; |
| 2105 } | 2052 } |
| 2106 break; | 2053 break; |
| 2107 } | 2054 } |
| 2108 default: | 2055 default: |
| 2109 return false; | 2056 return false; |
| 2110 } | 2057 } |
| 2111 | 2058 |
| 2112 return true; | 2059 return true; |
| 2113 } | 2060 } |
| 2114 | 2061 |
| 2115 bool QuicFramer::AppendTimestampFrame( | |
| 2116 const QuicCongestionFeedbackFrame& frame, | |
| 2117 QuicDataWriter* writer) { | |
| 2118 const CongestionFeedbackMessageTimestamp& timestamp = frame.timestamp; | |
| 2119 DCHECK_GE(numeric_limits<uint8>::max(), | |
| 2120 timestamp.received_packet_times.size()); | |
| 2121 if (timestamp.received_packet_times.size() > numeric_limits<uint8>::max()) { | |
| 2122 return false; | |
| 2123 } | |
| 2124 uint8 num_received_packets = timestamp.received_packet_times.size(); | |
| 2125 if (!writer->WriteBytes(&num_received_packets, 1)) { | |
| 2126 return false; | |
| 2127 } | |
| 2128 if (num_received_packets > 0) { | |
| 2129 TimeMap::const_iterator it = timestamp.received_packet_times.begin(); | |
| 2130 | |
| 2131 QuicPacketSequenceNumber lowest_sequence = it->first; | |
| 2132 if (!AppendPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER, | |
| 2133 lowest_sequence, writer)) { | |
| 2134 return false; | |
| 2135 } | |
| 2136 | |
| 2137 QuicTime lowest_time = it->second; | |
| 2138 if (!writer->WriteUInt64( | |
| 2139 lowest_time.Subtract(creation_time_).ToMicroseconds())) { | |
| 2140 return false; | |
| 2141 } | |
| 2142 | |
| 2143 for (++it; it != timestamp.received_packet_times.end(); ++it) { | |
| 2144 QuicPacketSequenceNumber sequence_delta = it->first - lowest_sequence; | |
| 2145 DCHECK_GE(numeric_limits<uint16>::max(), sequence_delta); | |
| 2146 if (sequence_delta > numeric_limits<uint16>::max()) { | |
| 2147 return false; | |
| 2148 } | |
| 2149 if (!writer->WriteUInt16(static_cast<uint16>(sequence_delta))) { | |
| 2150 return false; | |
| 2151 } | |
| 2152 | |
| 2153 int32 time_delta_us = it->second.Subtract(lowest_time).ToMicroseconds(); | |
| 2154 if (!writer->WriteBytes(&time_delta_us, sizeof(time_delta_us))) { | |
| 2155 return false; | |
| 2156 } | |
| 2157 } | |
| 2158 } | |
| 2159 return true; | |
| 2160 } | |
| 2161 | |
| 2162 bool QuicFramer::AppendStopWaitingFrame( | 2062 bool QuicFramer::AppendStopWaitingFrame( |
| 2163 const QuicPacketHeader& header, | 2063 const QuicPacketHeader& header, |
| 2164 const QuicStopWaitingFrame& frame, | 2064 const QuicStopWaitingFrame& frame, |
| 2165 QuicDataWriter* writer) { | 2065 QuicDataWriter* writer) { |
| 2166 DCHECK_GE(header.packet_sequence_number, frame.least_unacked); | 2066 DCHECK_GE(header.packet_sequence_number, frame.least_unacked); |
| 2167 const QuicPacketSequenceNumber least_unacked_delta = | 2067 const QuicPacketSequenceNumber least_unacked_delta = |
| 2168 header.packet_sequence_number - frame.least_unacked; | 2068 header.packet_sequence_number - frame.least_unacked; |
| 2169 const QuicPacketSequenceNumber length_shift = | 2069 const QuicPacketSequenceNumber length_shift = |
| 2170 header.public_header.sequence_number_length * 8; | 2070 header.public_header.sequence_number_length * 8; |
| 2171 if (!writer->WriteUInt8(frame.entropy_hash)) { | 2071 if (!writer->WriteUInt8(frame.entropy_hash)) { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2264 | 2164 |
| 2265 bool QuicFramer::RaiseError(QuicErrorCode error) { | 2165 bool QuicFramer::RaiseError(QuicErrorCode error) { |
| 2266 DVLOG(1) << "Error detail: " << detailed_error_; | 2166 DVLOG(1) << "Error detail: " << detailed_error_; |
| 2267 set_error(error); | 2167 set_error(error); |
| 2268 visitor_->OnError(this); | 2168 visitor_->OnError(this); |
| 2269 reader_.reset(NULL); | 2169 reader_.reset(NULL); |
| 2270 return false; | 2170 return false; |
| 2271 } | 2171 } |
| 2272 | 2172 |
| 2273 } // namespace net | 2173 } // namespace net |
| OLD | NEW |