| 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 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't | 5 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't |
| 6 // constantly adding and subtracting header sizes; this is ugly and error- | 6 // constantly adding and subtracting header sizes; this is ugly and error- |
| 7 // prone. | 7 // prone. |
| 8 | 8 |
| 9 #include "net/spdy/spdy_framer.h" | 9 #include "net/spdy/spdy_framer.h" |
| 10 | 10 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 }; | 46 }; |
| 47 | 47 |
| 48 // Adler ID for the SPDY header compressor dictionaries. Note that they are | 48 // Adler ID for the SPDY header compressor dictionaries. Note that they are |
| 49 // initialized lazily to avoid static initializers. | 49 // initialized lazily to avoid static initializers. |
| 50 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids; | 50 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids; |
| 51 | 51 |
| 52 // Creates a FlagsAndLength. | 52 // Creates a FlagsAndLength. |
| 53 FlagsAndLength CreateFlagsAndLength(SpdyControlFlags flags, size_t length) { | 53 FlagsAndLength CreateFlagsAndLength(SpdyControlFlags flags, size_t length) { |
| 54 DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask)); | 54 DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask)); |
| 55 FlagsAndLength flags_length; | 55 FlagsAndLength flags_length; |
| 56 flags_length.length_ = htonl(static_cast<uint32>(length)); | 56 flags_length.length_ = base::HostToNet32(static_cast<uint32>(length)); |
| 57 DCHECK_EQ(0, flags & ~kControlFlagsMask); | 57 DCHECK_EQ(0, flags & ~kControlFlagsMask); |
| 58 flags_length.flags_[0] = flags; | 58 flags_length.flags_[0] = flags; |
| 59 return flags_length; | 59 return flags_length; |
| 60 } | 60 } |
| 61 | 61 |
| 62 // By default is compression on or off. | 62 // By default is compression on or off. |
| 63 bool SpdyFramer::compression_default_ = true; | 63 bool SpdyFramer::compression_default_ = true; |
| 64 | 64 |
| 65 // The initial size of the control frame buffer; this is used internally | 65 // The initial size of the control frame buffer; this is used internally |
| 66 // as we parse through control frames. (It is exposed here for unit test | 66 // as we parse through control frames. (It is exposed here for unit test |
| (...skipping 29 matching lines...) Expand all Loading... |
| 96 } | 96 } |
| 97 #else | 97 #else |
| 98 #define CHANGE_STATE(newstate) (state_ = newstate) | 98 #define CHANGE_STATE(newstate) (state_ = newstate) |
| 99 #endif | 99 #endif |
| 100 | 100 |
| 101 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(int version, | 101 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(int version, |
| 102 uint32 wire) { | 102 uint32 wire) { |
| 103 if (version < 3) { | 103 if (version < 3) { |
| 104 ConvertFlagsAndIdForSpdy2(&wire); | 104 ConvertFlagsAndIdForSpdy2(&wire); |
| 105 } | 105 } |
| 106 return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff); | 106 return SettingsFlagsAndId(base::NetToHost32(wire) >> 24, |
| 107 base::NetToHost32(wire) & 0x00ffffff); |
| 107 } | 108 } |
| 108 | 109 |
| 109 SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id) | 110 SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id) |
| 110 : flags_(flags), id_(id & 0x00ffffff) { | 111 : flags_(flags), id_(id & 0x00ffffff) { |
| 111 DCHECK_GT(static_cast<uint32>(1 << 24), id); | 112 DCHECK_GT(static_cast<uint32>(1 << 24), id); |
| 112 } | 113 } |
| 113 | 114 |
| 114 uint32 SettingsFlagsAndId::GetWireFormat(int version) const { | 115 uint32 SettingsFlagsAndId::GetWireFormat(int version) const { |
| 115 uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24); | 116 uint32 wire = |
| 117 base::HostToNet32(id_ & 0x00ffffff) | base::HostToNet32(flags_ << 24); |
| 116 if (version < 3) { | 118 if (version < 3) { |
| 117 ConvertFlagsAndIdForSpdy2(&wire); | 119 ConvertFlagsAndIdForSpdy2(&wire); |
| 118 } | 120 } |
| 119 return wire; | 121 return wire; |
| 120 } | 122 } |
| 121 | 123 |
| 122 // SPDY 2 had a bug in it with respect to byte ordering of id/flags field. | 124 // SPDY 2 had a bug in it with respect to byte ordering of id/flags field. |
| 123 // This method is used to preserve buggy behavior and works on both | 125 // This method is used to preserve buggy behavior and works on both |
| 124 // little-endian and big-endian hosts. | 126 // little-endian and big-endian hosts. |
| 125 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3 | 127 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3 |
| (...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 return processed_bytes; | 785 return processed_bytes; |
| 784 } | 786 } |
| 785 | 787 |
| 786 bool SpdyFramer::ProcessSetting(const char* data) { | 788 bool SpdyFramer::ProcessSetting(const char* data) { |
| 787 // Extract fields. | 789 // Extract fields. |
| 788 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id. | 790 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id. |
| 789 const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data)); | 791 const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data)); |
| 790 SettingsFlagsAndId id_and_flags = | 792 SettingsFlagsAndId id_and_flags = |
| 791 SettingsFlagsAndId::FromWireFormat(spdy_version_, id_and_flags_wire); | 793 SettingsFlagsAndId::FromWireFormat(spdy_version_, id_and_flags_wire); |
| 792 uint8 flags = id_and_flags.flags(); | 794 uint8 flags = id_and_flags.flags(); |
| 793 uint32 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4))); | 795 uint32 value = |
| 796 base::NetToHost32(*(reinterpret_cast<const uint32*>(data + 4))); |
| 794 | 797 |
| 795 // Validate id. | 798 // Validate id. |
| 796 switch (id_and_flags.id()) { | 799 switch (id_and_flags.id()) { |
| 797 case SETTINGS_UPLOAD_BANDWIDTH: | 800 case SETTINGS_UPLOAD_BANDWIDTH: |
| 798 case SETTINGS_DOWNLOAD_BANDWIDTH: | 801 case SETTINGS_DOWNLOAD_BANDWIDTH: |
| 799 case SETTINGS_ROUND_TRIP_TIME: | 802 case SETTINGS_ROUND_TRIP_TIME: |
| 800 case SETTINGS_MAX_CONCURRENT_STREAMS: | 803 case SETTINGS_MAX_CONCURRENT_STREAMS: |
| 801 case SETTINGS_CURRENT_CWND: | 804 case SETTINGS_CURRENT_CWND: |
| 802 case SETTINGS_DOWNLOAD_RETRANS_RATE: | 805 case SETTINGS_DOWNLOAD_RETRANS_RATE: |
| 803 case SETTINGS_INITIAL_WINDOW_SIZE: | 806 case SETTINGS_INITIAL_WINDOW_SIZE: |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 998 bool SpdyFramer::ParseSettings(const SpdySettingsControlFrame* frame, | 1001 bool SpdyFramer::ParseSettings(const SpdySettingsControlFrame* frame, |
| 999 SpdySettings* settings) { | 1002 SpdySettings* settings) { |
| 1000 DCHECK_EQ(frame->type(), SETTINGS); | 1003 DCHECK_EQ(frame->type(), SETTINGS); |
| 1001 DCHECK(settings); | 1004 DCHECK(settings); |
| 1002 | 1005 |
| 1003 SpdyFrameReader parser(frame->header_block(), frame->header_block_len()); | 1006 SpdyFrameReader parser(frame->header_block(), frame->header_block_len()); |
| 1004 for (size_t index = 0; index < frame->num_entries(); ++index) { | 1007 for (size_t index = 0; index < frame->num_entries(); ++index) { |
| 1005 uint32 id_and_flags_wire; | 1008 uint32 id_and_flags_wire; |
| 1006 uint32 value; | 1009 uint32 value; |
| 1007 // SettingsFlagsAndId accepts off-the-wire (network byte order) data, so we | 1010 // SettingsFlagsAndId accepts off-the-wire (network byte order) data, so we |
| 1008 // use ReadBytes() instead of ReadUInt32() as the latter calls ntohl(). | 1011 // use ReadBytes() instead of ReadUInt32(), which calls base::NetToHost32(). |
| 1009 if (!parser.ReadBytes(&id_and_flags_wire, 4)) { | 1012 if (!parser.ReadBytes(&id_and_flags_wire, 4)) { |
| 1010 return false; | 1013 return false; |
| 1011 } | 1014 } |
| 1012 if (!parser.ReadUInt32(&value)) | 1015 if (!parser.ReadUInt32(&value)) |
| 1013 return false; | 1016 return false; |
| 1014 SettingsFlagsAndId id_and_flags = | 1017 SettingsFlagsAndId id_and_flags = |
| 1015 SettingsFlagsAndId::FromWireFormat(frame->version(), id_and_flags_wire); | 1018 SettingsFlagsAndId::FromWireFormat(frame->version(), id_and_flags_wire); |
| 1016 settings->insert(settings->end(), std::make_pair(id_and_flags, value)); | 1019 settings->insert(settings->end(), std::make_pair(id_and_flags, value)); |
| 1017 } | 1020 } |
| 1018 return true; | 1021 return true; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1069 frame.WriteUInt16(SYN_STREAM); | 1072 frame.WriteUInt16(SYN_STREAM); |
| 1070 frame.WriteBytes(&flags_length, sizeof(flags_length)); | 1073 frame.WriteBytes(&flags_length, sizeof(flags_length)); |
| 1071 frame.WriteUInt32(stream_id); | 1074 frame.WriteUInt32(stream_id); |
| 1072 frame.WriteUInt32(associated_stream_id); | 1075 frame.WriteUInt32(associated_stream_id); |
| 1073 // Cap as appropriate. | 1076 // Cap as appropriate. |
| 1074 if (priority > GetLowestPriority()) { | 1077 if (priority > GetLowestPriority()) { |
| 1075 DLOG(ERROR) << "Priority out-of-bounds."; | 1078 DLOG(ERROR) << "Priority out-of-bounds."; |
| 1076 priority = GetLowestPriority(); | 1079 priority = GetLowestPriority(); |
| 1077 } | 1080 } |
| 1078 // Priority is 2 bits for <spdy3, 3 bits otherwise. | 1081 // Priority is 2 bits for <spdy3, 3 bits otherwise. |
| 1079 frame.WriteUInt16(ntohs(priority) << (spdy_version_ < 3 ? 6 : 5)); | 1082 frame.WriteUInt16(base::NetToHost16(priority) << (spdy_version_ < 3 ? 6 : 5)); |
| 1080 WriteHeaderBlock(&frame, headers); | 1083 WriteHeaderBlock(&frame, headers); |
| 1081 | 1084 |
| 1082 scoped_ptr<SpdySynStreamControlFrame> syn_frame( | 1085 scoped_ptr<SpdySynStreamControlFrame> syn_frame( |
| 1083 reinterpret_cast<SpdySynStreamControlFrame*>(frame.take())); | 1086 reinterpret_cast<SpdySynStreamControlFrame*>(frame.take())); |
| 1084 if (compressed) { | 1087 if (compressed) { |
| 1085 return reinterpret_cast<SpdySynStreamControlFrame*>( | 1088 return reinterpret_cast<SpdySynStreamControlFrame*>( |
| 1086 CompressControlFrame(*syn_frame.get())); | 1089 CompressControlFrame(*syn_frame.get())); |
| 1087 } | 1090 } |
| 1088 return syn_frame.release(); | 1091 return syn_frame.release(); |
| 1089 } | 1092 } |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1288 SpdyDataFrame* SpdyFramer::CreateDataFrame(SpdyStreamId stream_id, | 1291 SpdyDataFrame* SpdyFramer::CreateDataFrame(SpdyStreamId stream_id, |
| 1289 const char* data, | 1292 const char* data, |
| 1290 uint32 len, SpdyDataFlags flags) { | 1293 uint32 len, SpdyDataFlags flags) { |
| 1291 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); | 1294 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); |
| 1292 | 1295 |
| 1293 SpdyFrameBuilder frame(SpdyDataFrame::size() + len); | 1296 SpdyFrameBuilder frame(SpdyDataFrame::size() + len); |
| 1294 frame.WriteUInt32(stream_id); | 1297 frame.WriteUInt32(stream_id); |
| 1295 | 1298 |
| 1296 DCHECK_EQ(0u, len & ~static_cast<size_t>(kLengthMask)); | 1299 DCHECK_EQ(0u, len & ~static_cast<size_t>(kLengthMask)); |
| 1297 FlagsAndLength flags_length; | 1300 FlagsAndLength flags_length; |
| 1298 flags_length.length_ = htonl(len); | 1301 flags_length.length_ = base::HostToNet32(len); |
| 1299 DCHECK_EQ(0, flags & ~kDataFlagsMask); | 1302 DCHECK_EQ(0, flags & ~kDataFlagsMask); |
| 1300 flags_length.flags_[0] = flags; | 1303 flags_length.flags_[0] = flags; |
| 1301 frame.WriteBytes(&flags_length, sizeof(flags_length)); | 1304 frame.WriteBytes(&flags_length, sizeof(flags_length)); |
| 1302 | 1305 |
| 1303 frame.WriteBytes(data, len); | 1306 frame.WriteBytes(data, len); |
| 1304 scoped_ptr<SpdyFrame> data_frame(frame.take()); | 1307 scoped_ptr<SpdyFrame> data_frame(frame.take()); |
| 1305 SpdyDataFrame* rv; | 1308 SpdyDataFrame* rv; |
| 1306 if (flags & DATA_FLAG_COMPRESSED) { | 1309 if (flags & DATA_FLAG_COMPRESSED) { |
| 1307 LOG(DFATAL) << "DATA_FLAG_COMPRESSED invalid for " << display_protocol_ | 1310 LOG(DFATAL) << "DATA_FLAG_COMPRESSED invalid for " << display_protocol_ |
| 1308 << "."; | 1311 << "."; |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1768 | 1771 |
| 1769 void SpdyFramer::set_validate_control_frame_sizes(bool value) { | 1772 void SpdyFramer::set_validate_control_frame_sizes(bool value) { |
| 1770 validate_control_frame_sizes_ = value; | 1773 validate_control_frame_sizes_ = value; |
| 1771 } | 1774 } |
| 1772 | 1775 |
| 1773 void SpdyFramer::set_enable_compression_default(bool value) { | 1776 void SpdyFramer::set_enable_compression_default(bool value) { |
| 1774 compression_default_ = value; | 1777 compression_default_ = value; |
| 1775 } | 1778 } |
| 1776 | 1779 |
| 1777 } // namespace spdy | 1780 } // namespace spdy |
| OLD | NEW |