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/spdy/spdy_session.h" | 5 #include "net/spdy/spdy_session.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> |
8 #include <map> | 9 #include <map> |
9 | 10 |
10 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
11 #include "base/bind.h" | 12 #include "base/bind.h" |
12 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
13 #include "base/location.h" | 14 #include "base/location.h" |
14 #include "base/logging.h" | 15 #include "base/logging.h" |
15 #include "base/metrics/field_trial.h" | 16 #include "base/metrics/field_trial.h" |
16 #include "base/metrics/histogram_macros.h" | 17 #include "base/metrics/histogram_macros.h" |
17 #include "base/metrics/sparse_histogram.h" | 18 #include "base/metrics/sparse_histogram.h" |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 167 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
167 dict->SetString("host", host_port_pair.ToString()); | 168 dict->SetString("host", host_port_pair.ToString()); |
168 dict->SetBoolean("clear_persisted", clear_persisted); | 169 dict->SetBoolean("clear_persisted", clear_persisted); |
169 return dict.Pass(); | 170 return dict.Pass(); |
170 } | 171 } |
171 | 172 |
172 scoped_ptr<base::Value> NetLogSpdySettingCallback( | 173 scoped_ptr<base::Value> NetLogSpdySettingCallback( |
173 SpdySettingsIds id, | 174 SpdySettingsIds id, |
174 const SpdyMajorVersion protocol_version, | 175 const SpdyMajorVersion protocol_version, |
175 SpdySettingsFlags flags, | 176 SpdySettingsFlags flags, |
176 uint32 value, | 177 uint32_t value, |
177 NetLogCaptureMode /* capture_mode */) { | 178 NetLogCaptureMode /* capture_mode */) { |
178 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 179 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
179 dict->SetInteger("id", | 180 dict->SetInteger("id", |
180 SpdyConstants::SerializeSettingId(protocol_version, id)); | 181 SpdyConstants::SerializeSettingId(protocol_version, id)); |
181 dict->SetInteger("flags", flags); | 182 dict->SetInteger("flags", flags); |
182 dict->SetInteger("value", value); | 183 dict->SetInteger("value", value); |
183 return dict.Pass(); | 184 return dict.Pass(); |
184 } | 185 } |
185 | 186 |
186 scoped_ptr<base::Value> NetLogSpdySendSettingsCallback( | 187 scoped_ptr<base::Value> NetLogSpdySendSettingsCallback( |
187 const SettingsMap* settings, | 188 const SettingsMap* settings, |
188 const SpdyMajorVersion protocol_version, | 189 const SpdyMajorVersion protocol_version, |
189 NetLogCaptureMode /* capture_mode */) { | 190 NetLogCaptureMode /* capture_mode */) { |
190 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 191 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
191 scoped_ptr<base::ListValue> settings_list(new base::ListValue()); | 192 scoped_ptr<base::ListValue> settings_list(new base::ListValue()); |
192 for (SettingsMap::const_iterator it = settings->begin(); | 193 for (SettingsMap::const_iterator it = settings->begin(); |
193 it != settings->end(); ++it) { | 194 it != settings->end(); ++it) { |
194 const SpdySettingsIds id = it->first; | 195 const SpdySettingsIds id = it->first; |
195 const SpdySettingsFlags flags = it->second.first; | 196 const SpdySettingsFlags flags = it->second.first; |
196 const uint32 value = it->second.second; | 197 const uint32_t value = it->second.second; |
197 settings_list->Append(new base::StringValue(base::StringPrintf( | 198 settings_list->Append(new base::StringValue(base::StringPrintf( |
198 "[id:%u flags:%u value:%u]", | 199 "[id:%u flags:%u value:%u]", |
199 SpdyConstants::SerializeSettingId(protocol_version, id), | 200 SpdyConstants::SerializeSettingId(protocol_version, id), |
200 flags, | 201 flags, |
201 value))); | 202 value))); |
202 } | 203 } |
203 dict->Set("settings", settings_list.Pass()); | 204 dict->Set("settings", settings_list.Pass()); |
204 return dict.Pass(); | 205 return dict.Pass(); |
205 } | 206 } |
206 | 207 |
207 scoped_ptr<base::Value> NetLogSpdyWindowUpdateFrameCallback( | 208 scoped_ptr<base::Value> NetLogSpdyWindowUpdateFrameCallback( |
208 SpdyStreamId stream_id, | 209 SpdyStreamId stream_id, |
209 uint32 delta, | 210 uint32_t delta, |
210 NetLogCaptureMode /* capture_mode */) { | 211 NetLogCaptureMode /* capture_mode */) { |
211 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 212 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
212 dict->SetInteger("stream_id", static_cast<int>(stream_id)); | 213 dict->SetInteger("stream_id", static_cast<int>(stream_id)); |
213 dict->SetInteger("delta", delta); | 214 dict->SetInteger("delta", delta); |
214 return dict.Pass(); | 215 return dict.Pass(); |
215 } | 216 } |
216 | 217 |
217 scoped_ptr<base::Value> NetLogSpdySessionWindowUpdateCallback( | 218 scoped_ptr<base::Value> NetLogSpdySessionWindowUpdateCallback( |
218 int32 delta, | 219 int32_t delta, |
219 int32 window_size, | 220 int32_t window_size, |
220 NetLogCaptureMode /* capture_mode */) { | 221 NetLogCaptureMode /* capture_mode */) { |
221 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 222 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
222 dict->SetInteger("delta", delta); | 223 dict->SetInteger("delta", delta); |
223 dict->SetInteger("window_size", window_size); | 224 dict->SetInteger("window_size", window_size); |
224 return dict.Pass(); | 225 return dict.Pass(); |
225 } | 226 } |
226 | 227 |
227 scoped_ptr<base::Value> NetLogSpdyDataCallback( | 228 scoped_ptr<base::Value> NetLogSpdyDataCallback( |
228 SpdyStreamId stream_id, | 229 SpdyStreamId stream_id, |
229 int size, | 230 int size, |
(...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 base::Bind(&NetLogSpdyDataCallback, stream_id, | 1258 base::Bind(&NetLogSpdyDataCallback, stream_id, |
1258 effective_len, (flags & DATA_FLAG_FIN) != 0)); | 1259 effective_len, (flags & DATA_FLAG_FIN) != 0)); |
1259 } | 1260 } |
1260 | 1261 |
1261 // Send PrefacePing for DATA_FRAMEs with nonzero payload size. | 1262 // Send PrefacePing for DATA_FRAMEs with nonzero payload size. |
1262 if (effective_len > 0) | 1263 if (effective_len > 0) |
1263 SendPrefacePingIfNoneInFlight(); | 1264 SendPrefacePingIfNoneInFlight(); |
1264 | 1265 |
1265 // TODO(mbelshe): reduce memory copies here. | 1266 // TODO(mbelshe): reduce memory copies here. |
1266 DCHECK(buffered_spdy_framer_.get()); | 1267 DCHECK(buffered_spdy_framer_.get()); |
1267 scoped_ptr<SpdyFrame> frame( | 1268 scoped_ptr<SpdyFrame> frame(buffered_spdy_framer_->CreateDataFrame( |
1268 buffered_spdy_framer_->CreateDataFrame( | 1269 stream_id, data->data(), static_cast<uint32_t>(effective_len), flags)); |
1269 stream_id, data->data(), | |
1270 static_cast<uint32>(effective_len), flags)); | |
1271 | 1270 |
1272 scoped_ptr<SpdyBuffer> data_buffer(new SpdyBuffer(frame.Pass())); | 1271 scoped_ptr<SpdyBuffer> data_buffer(new SpdyBuffer(frame.Pass())); |
1273 | 1272 |
1274 // Send window size is based on payload size, so nothing to do if this is | 1273 // Send window size is based on payload size, so nothing to do if this is |
1275 // just a FIN with no payload. | 1274 // just a FIN with no payload. |
1276 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION && | 1275 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION && |
1277 effective_len != 0) { | 1276 effective_len != 0) { |
1278 DecreaseSendWindowSize(static_cast<int32>(effective_len)); | 1277 DecreaseSendWindowSize(static_cast<int32_t>(effective_len)); |
1279 data_buffer->AddConsumeCallback( | 1278 data_buffer->AddConsumeCallback( |
1280 base::Bind(&SpdySession::OnWriteBufferConsumed, | 1279 base::Bind(&SpdySession::OnWriteBufferConsumed, |
1281 weak_factory_.GetWeakPtr(), | 1280 weak_factory_.GetWeakPtr(), |
1282 static_cast<size_t>(effective_len))); | 1281 static_cast<size_t>(effective_len))); |
1283 } | 1282 } |
1284 | 1283 |
1285 return data_buffer.Pass(); | 1284 return data_buffer.Pass(); |
1286 } | 1285 } |
1287 | 1286 |
1288 void SpdySession::CloseActiveStream(SpdyStreamId stream_id, int status) { | 1287 void SpdySession::CloseActiveStream(SpdyStreamId stream_id, int status) { |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1505 return result; | 1504 return result; |
1506 } | 1505 } |
1507 CHECK_LE(result, kReadBufferSize); | 1506 CHECK_LE(result, kReadBufferSize); |
1508 total_bytes_received_ += result; | 1507 total_bytes_received_ += result; |
1509 | 1508 |
1510 last_activity_time_ = time_func_(); | 1509 last_activity_time_ = time_func_(); |
1511 | 1510 |
1512 DCHECK(buffered_spdy_framer_.get()); | 1511 DCHECK(buffered_spdy_framer_.get()); |
1513 char* data = read_buffer_->data(); | 1512 char* data = read_buffer_->data(); |
1514 while (result > 0) { | 1513 while (result > 0) { |
1515 uint32 bytes_processed = buffered_spdy_framer_->ProcessInput(data, result); | 1514 uint32_t bytes_processed = |
| 1515 buffered_spdy_framer_->ProcessInput(data, result); |
1516 result -= bytes_processed; | 1516 result -= bytes_processed; |
1517 data += bytes_processed; | 1517 data += bytes_processed; |
1518 | 1518 |
1519 if (availability_state_ == STATE_DRAINING) { | 1519 if (availability_state_ == STATE_DRAINING) { |
1520 return ERR_CONNECTION_CLOSED; | 1520 return ERR_CONNECTION_CLOSED; |
1521 } | 1521 } |
1522 | 1522 |
1523 DCHECK_EQ(buffered_spdy_framer_->error_code(), SpdyFramer::SPDY_NO_ERROR); | 1523 DCHECK_EQ(buffered_spdy_framer_->error_code(), SpdyFramer::SPDY_NO_ERROR); |
1524 } | 1524 } |
1525 | 1525 |
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2118 // |unacked_recv_window_bytes_| properly even when the stream is | 2118 // |unacked_recv_window_bytes_| properly even when the stream is |
2119 // inactive (since the other side has still reduced its session send | 2119 // inactive (since the other side has still reduced its session send |
2120 // window). | 2120 // window). |
2121 scoped_ptr<SpdyBuffer> buffer; | 2121 scoped_ptr<SpdyBuffer> buffer; |
2122 if (data) { | 2122 if (data) { |
2123 DCHECK_GT(len, 0u); | 2123 DCHECK_GT(len, 0u); |
2124 CHECK_LE(len, static_cast<size_t>(kReadBufferSize)); | 2124 CHECK_LE(len, static_cast<size_t>(kReadBufferSize)); |
2125 buffer.reset(new SpdyBuffer(data, len)); | 2125 buffer.reset(new SpdyBuffer(data, len)); |
2126 | 2126 |
2127 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { | 2127 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { |
2128 DecreaseRecvWindowSize(static_cast<int32>(len)); | 2128 DecreaseRecvWindowSize(static_cast<int32_t>(len)); |
2129 buffer->AddConsumeCallback( | 2129 buffer->AddConsumeCallback( |
2130 base::Bind(&SpdySession::OnReadBufferConsumed, | 2130 base::Bind(&SpdySession::OnReadBufferConsumed, |
2131 weak_factory_.GetWeakPtr())); | 2131 weak_factory_.GetWeakPtr())); |
2132 } | 2132 } |
2133 } else { | 2133 } else { |
2134 DCHECK_EQ(len, 0u); | 2134 DCHECK_EQ(len, 0u); |
2135 } | 2135 } |
2136 | 2136 |
2137 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 2137 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
2138 | 2138 |
(...skipping 19 matching lines...) Expand all Loading... |
2158 void SpdySession::OnStreamPadding(SpdyStreamId stream_id, size_t len) { | 2158 void SpdySession::OnStreamPadding(SpdyStreamId stream_id, size_t len) { |
2159 CHECK(in_io_loop_); | 2159 CHECK(in_io_loop_); |
2160 | 2160 |
2161 if (flow_control_state_ != FLOW_CONTROL_STREAM_AND_SESSION) | 2161 if (flow_control_state_ != FLOW_CONTROL_STREAM_AND_SESSION) |
2162 return; | 2162 return; |
2163 | 2163 |
2164 // Decrease window size because padding bytes are received. | 2164 // Decrease window size because padding bytes are received. |
2165 // Increase window size because padding bytes are consumed (by discarding). | 2165 // Increase window size because padding bytes are consumed (by discarding). |
2166 // Net result: |session_unacked_recv_window_bytes_| increases by |len|, | 2166 // Net result: |session_unacked_recv_window_bytes_| increases by |len|, |
2167 // |session_recv_window_size_| does not change. | 2167 // |session_recv_window_size_| does not change. |
2168 DecreaseRecvWindowSize(static_cast<int32>(len)); | 2168 DecreaseRecvWindowSize(static_cast<int32_t>(len)); |
2169 IncreaseRecvWindowSize(static_cast<int32>(len)); | 2169 IncreaseRecvWindowSize(static_cast<int32_t>(len)); |
2170 | 2170 |
2171 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 2171 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
2172 if (it == active_streams_.end()) | 2172 if (it == active_streams_.end()) |
2173 return; | 2173 return; |
2174 it->second.stream->OnPaddingConsumed(len); | 2174 it->second.stream->OnPaddingConsumed(len); |
2175 } | 2175 } |
2176 | 2176 |
2177 SpdyHeadersHandlerInterface* SpdySession::OnHeaderFrameStart( | 2177 SpdyHeadersHandlerInterface* SpdySession::OnHeaderFrameStart( |
2178 SpdyStreamId stream_id) { | 2178 SpdyStreamId stream_id) { |
2179 LOG(FATAL); | 2179 LOG(FATAL); |
(...skipping 21 matching lines...) Expand all Loading... |
2201 SpdySettingsIR settings_ir; | 2201 SpdySettingsIR settings_ir; |
2202 settings_ir.set_is_ack(true); | 2202 settings_ir.set_is_ack(true); |
2203 EnqueueSessionWrite( | 2203 EnqueueSessionWrite( |
2204 HIGHEST, | 2204 HIGHEST, |
2205 SETTINGS, | 2205 SETTINGS, |
2206 scoped_ptr<SpdyFrame>( | 2206 scoped_ptr<SpdyFrame>( |
2207 buffered_spdy_framer_->SerializeFrame(settings_ir))); | 2207 buffered_spdy_framer_->SerializeFrame(settings_ir))); |
2208 } | 2208 } |
2209 } | 2209 } |
2210 | 2210 |
2211 void SpdySession::OnSetting(SpdySettingsIds id, | 2211 void SpdySession::OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) { |
2212 uint8 flags, | |
2213 uint32 value) { | |
2214 CHECK(in_io_loop_); | 2212 CHECK(in_io_loop_); |
2215 | 2213 |
2216 HandleSetting(id, value); | 2214 HandleSetting(id, value); |
2217 http_server_properties_->SetSpdySetting( | 2215 http_server_properties_->SetSpdySetting( |
2218 host_port_pair(), | 2216 host_port_pair(), |
2219 id, | 2217 id, |
2220 static_cast<SpdySettingsFlags>(flags), | 2218 static_cast<SpdySettingsFlags>(flags), |
2221 value); | 2219 value); |
2222 received_settings_ = true; | 2220 received_settings_ = true; |
2223 | 2221 |
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2810 &headers, stream_id, promised_stream_id)); | 2808 &headers, stream_id, promised_stream_id)); |
2811 } | 2809 } |
2812 | 2810 |
2813 // Any priority will do. | 2811 // Any priority will do. |
2814 // TODO(baranovich): pass parent stream id priority? | 2812 // TODO(baranovich): pass parent stream id priority? |
2815 if (!TryCreatePushStream(promised_stream_id, stream_id, 0, headers)) | 2813 if (!TryCreatePushStream(promised_stream_id, stream_id, 0, headers)) |
2816 return; | 2814 return; |
2817 } | 2815 } |
2818 | 2816 |
2819 void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id, | 2817 void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id, |
2820 uint32 delta_window_size) { | 2818 uint32_t delta_window_size) { |
2821 CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); | 2819 CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); |
2822 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); | 2820 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); |
2823 CHECK(it != active_streams_.end()); | 2821 CHECK(it != active_streams_.end()); |
2824 CHECK_EQ(it->second.stream->stream_id(), stream_id); | 2822 CHECK_EQ(it->second.stream->stream_id(), stream_id); |
2825 SendWindowUpdateFrame( | 2823 SendWindowUpdateFrame( |
2826 stream_id, delta_window_size, it->second.stream->priority()); | 2824 stream_id, delta_window_size, it->second.stream->priority()); |
2827 } | 2825 } |
2828 | 2826 |
2829 void SpdySession::SendInitialData() { | 2827 void SpdySession::SendInitialData() { |
2830 DCHECK(enable_sending_initial_data_); | 2828 DCHECK(enable_sending_initial_data_); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2873 // Finally, notify the server about the settings they have | 2871 // Finally, notify the server about the settings they have |
2874 // previously told us to use when communicating with them (after | 2872 // previously told us to use when communicating with them (after |
2875 // applying them). | 2873 // applying them). |
2876 const SettingsMap& server_settings_map = | 2874 const SettingsMap& server_settings_map = |
2877 http_server_properties_->GetSpdySettings(host_port_pair()); | 2875 http_server_properties_->GetSpdySettings(host_port_pair()); |
2878 if (server_settings_map.empty()) | 2876 if (server_settings_map.empty()) |
2879 return; | 2877 return; |
2880 | 2878 |
2881 SettingsMap::const_iterator it = | 2879 SettingsMap::const_iterator it = |
2882 server_settings_map.find(SETTINGS_CURRENT_CWND); | 2880 server_settings_map.find(SETTINGS_CURRENT_CWND); |
2883 uint32 cwnd = (it != server_settings_map.end()) ? it->second.second : 0; | 2881 uint32_t cwnd = (it != server_settings_map.end()) ? it->second.second : 0; |
2884 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwndSent", cwnd, 1, 200, 100); | 2882 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwndSent", cwnd, 1, 200, 100); |
2885 | 2883 |
2886 for (SettingsMap::const_iterator it = server_settings_map.begin(); | 2884 for (SettingsMap::const_iterator it = server_settings_map.begin(); |
2887 it != server_settings_map.end(); ++it) { | 2885 it != server_settings_map.end(); ++it) { |
2888 const SpdySettingsIds new_id = it->first; | 2886 const SpdySettingsIds new_id = it->first; |
2889 const uint32 new_val = it->second.second; | 2887 const uint32_t new_val = it->second.second; |
2890 HandleSetting(new_id, new_val); | 2888 HandleSetting(new_id, new_val); |
2891 } | 2889 } |
2892 | 2890 |
2893 SendSettings(server_settings_map); | 2891 SendSettings(server_settings_map); |
2894 } | 2892 } |
2895 } | 2893 } |
2896 | 2894 |
2897 | 2895 |
2898 void SpdySession::SendSettings(const SettingsMap& settings) { | 2896 void SpdySession::SendSettings(const SettingsMap& settings) { |
2899 const SpdyMajorVersion protocol_version = GetProtocolVersion(); | 2897 const SpdyMajorVersion protocol_version = GetProtocolVersion(); |
2900 net_log_.AddEvent( | 2898 net_log_.AddEvent( |
2901 NetLog::TYPE_HTTP2_SESSION_SEND_SETTINGS, | 2899 NetLog::TYPE_HTTP2_SESSION_SEND_SETTINGS, |
2902 base::Bind(&NetLogSpdySendSettingsCallback, &settings, protocol_version)); | 2900 base::Bind(&NetLogSpdySendSettingsCallback, &settings, protocol_version)); |
2903 // Create the SETTINGS frame and send it. | 2901 // Create the SETTINGS frame and send it. |
2904 DCHECK(buffered_spdy_framer_.get()); | 2902 DCHECK(buffered_spdy_framer_.get()); |
2905 scoped_ptr<SpdyFrame> settings_frame( | 2903 scoped_ptr<SpdyFrame> settings_frame( |
2906 buffered_spdy_framer_->CreateSettings(settings)); | 2904 buffered_spdy_framer_->CreateSettings(settings)); |
2907 sent_settings_ = true; | 2905 sent_settings_ = true; |
2908 EnqueueSessionWrite(HIGHEST, SETTINGS, settings_frame.Pass()); | 2906 EnqueueSessionWrite(HIGHEST, SETTINGS, settings_frame.Pass()); |
2909 } | 2907 } |
2910 | 2908 |
2911 void SpdySession::HandleSetting(uint32 id, uint32 value) { | 2909 void SpdySession::HandleSetting(uint32_t id, uint32_t value) { |
2912 switch (id) { | 2910 switch (id) { |
2913 case SETTINGS_MAX_CONCURRENT_STREAMS: | 2911 case SETTINGS_MAX_CONCURRENT_STREAMS: |
2914 max_concurrent_streams_ = std::min(static_cast<size_t>(value), | 2912 max_concurrent_streams_ = std::min(static_cast<size_t>(value), |
2915 kMaxConcurrentStreamLimit); | 2913 kMaxConcurrentStreamLimit); |
2916 ProcessPendingStreamRequests(); | 2914 ProcessPendingStreamRequests(); |
2917 break; | 2915 break; |
2918 case SETTINGS_INITIAL_WINDOW_SIZE: { | 2916 case SETTINGS_INITIAL_WINDOW_SIZE: { |
2919 if (flow_control_state_ < FLOW_CONTROL_STREAM) { | 2917 if (flow_control_state_ < FLOW_CONTROL_STREAM) { |
2920 net_log().AddEvent( | 2918 net_log().AddEvent( |
2921 NetLog::TYPE_HTTP2_SESSION_INITIAL_WINDOW_SIZE_NO_FLOW_CONTROL); | 2919 NetLog::TYPE_HTTP2_SESSION_INITIAL_WINDOW_SIZE_NO_FLOW_CONTROL); |
2922 return; | 2920 return; |
2923 } | 2921 } |
2924 | 2922 |
2925 if (value > static_cast<uint32>(kint32max)) { | 2923 if (value > static_cast<uint32_t>(std::numeric_limits<int32_t>::max())) { |
2926 net_log().AddEvent( | 2924 net_log().AddEvent( |
2927 NetLog::TYPE_HTTP2_SESSION_INITIAL_WINDOW_SIZE_OUT_OF_RANGE, | 2925 NetLog::TYPE_HTTP2_SESSION_INITIAL_WINDOW_SIZE_OUT_OF_RANGE, |
2928 NetLog::IntCallback("initial_window_size", value)); | 2926 NetLog::IntCallback("initial_window_size", value)); |
2929 return; | 2927 return; |
2930 } | 2928 } |
2931 | 2929 |
2932 // SETTINGS_INITIAL_WINDOW_SIZE updates initial_send_window_size_ only. | 2930 // SETTINGS_INITIAL_WINDOW_SIZE updates initial_send_window_size_ only. |
2933 int32 delta_window_size = | 2931 int32_t delta_window_size = |
2934 static_cast<int32>(value) - stream_initial_send_window_size_; | 2932 static_cast<int32_t>(value) - stream_initial_send_window_size_; |
2935 stream_initial_send_window_size_ = static_cast<int32>(value); | 2933 stream_initial_send_window_size_ = static_cast<int32_t>(value); |
2936 UpdateStreamsSendWindowSize(delta_window_size); | 2934 UpdateStreamsSendWindowSize(delta_window_size); |
2937 net_log().AddEvent( | 2935 net_log().AddEvent( |
2938 NetLog::TYPE_HTTP2_SESSION_UPDATE_STREAMS_SEND_WINDOW_SIZE, | 2936 NetLog::TYPE_HTTP2_SESSION_UPDATE_STREAMS_SEND_WINDOW_SIZE, |
2939 NetLog::IntCallback("delta_window_size", delta_window_size)); | 2937 NetLog::IntCallback("delta_window_size", delta_window_size)); |
2940 break; | 2938 break; |
2941 } | 2939 } |
2942 } | 2940 } |
2943 } | 2941 } |
2944 | 2942 |
2945 void SpdySession::UpdateStreamsSendWindowSize(int32 delta_window_size) { | 2943 void SpdySession::UpdateStreamsSendWindowSize(int32_t delta_window_size) { |
2946 DCHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); | 2944 DCHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); |
2947 for (ActiveStreamMap::iterator it = active_streams_.begin(); | 2945 for (ActiveStreamMap::iterator it = active_streams_.begin(); |
2948 it != active_streams_.end(); ++it) { | 2946 it != active_streams_.end(); ++it) { |
2949 it->second.stream->AdjustSendWindowSize(delta_window_size); | 2947 it->second.stream->AdjustSendWindowSize(delta_window_size); |
2950 } | 2948 } |
2951 | 2949 |
2952 for (CreatedStreamSet::const_iterator it = created_streams_.begin(); | 2950 for (CreatedStreamSet::const_iterator it = created_streams_.begin(); |
2953 it != created_streams_.end(); it++) { | 2951 it != created_streams_.end(); it++) { |
2954 (*it)->AdjustSendWindowSize(delta_window_size); | 2952 (*it)->AdjustSendWindowSize(delta_window_size); |
2955 } | 2953 } |
2956 } | 2954 } |
2957 | 2955 |
2958 void SpdySession::SendPrefacePingIfNoneInFlight() { | 2956 void SpdySession::SendPrefacePingIfNoneInFlight() { |
2959 if (pings_in_flight_ || !enable_ping_based_connection_checking_) | 2957 if (pings_in_flight_ || !enable_ping_based_connection_checking_) |
2960 return; | 2958 return; |
2961 | 2959 |
2962 base::TimeTicks now = time_func_(); | 2960 base::TimeTicks now = time_func_(); |
2963 // If there is no activity in the session, then send a preface-PING. | 2961 // If there is no activity in the session, then send a preface-PING. |
2964 if ((now - last_activity_time_) > connection_at_risk_of_loss_time_) | 2962 if ((now - last_activity_time_) > connection_at_risk_of_loss_time_) |
2965 SendPrefacePing(); | 2963 SendPrefacePing(); |
2966 } | 2964 } |
2967 | 2965 |
2968 void SpdySession::SendPrefacePing() { | 2966 void SpdySession::SendPrefacePing() { |
2969 WritePingFrame(next_ping_id_, false); | 2967 WritePingFrame(next_ping_id_, false); |
2970 } | 2968 } |
2971 | 2969 |
2972 void SpdySession::SendWindowUpdateFrame(SpdyStreamId stream_id, | 2970 void SpdySession::SendWindowUpdateFrame(SpdyStreamId stream_id, |
2973 uint32 delta_window_size, | 2971 uint32_t delta_window_size, |
2974 RequestPriority priority) { | 2972 RequestPriority priority) { |
2975 CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); | 2973 CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); |
2976 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); | 2974 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); |
2977 if (it != active_streams_.end()) { | 2975 if (it != active_streams_.end()) { |
2978 CHECK_EQ(it->second.stream->stream_id(), stream_id); | 2976 CHECK_EQ(it->second.stream->stream_id(), stream_id); |
2979 } else { | 2977 } else { |
2980 CHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); | 2978 CHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); |
2981 CHECK_EQ(stream_id, kSessionFlowControlStreamId); | 2979 CHECK_EQ(stream_id, kSessionFlowControlStreamId); |
2982 } | 2980 } |
2983 | 2981 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3088 stalled_streams_ > 0 ? 1 : 0, 2); | 3086 stalled_streams_ > 0 ? 1 : 0, 2); |
3089 | 3087 |
3090 if (received_settings_) { | 3088 if (received_settings_) { |
3091 // Enumerate the saved settings, and set histograms for it. | 3089 // Enumerate the saved settings, and set histograms for it. |
3092 const SettingsMap& settings_map = | 3090 const SettingsMap& settings_map = |
3093 http_server_properties_->GetSpdySettings(host_port_pair()); | 3091 http_server_properties_->GetSpdySettings(host_port_pair()); |
3094 | 3092 |
3095 SettingsMap::const_iterator it; | 3093 SettingsMap::const_iterator it; |
3096 for (it = settings_map.begin(); it != settings_map.end(); ++it) { | 3094 for (it = settings_map.begin(); it != settings_map.end(); ++it) { |
3097 const SpdySettingsIds id = it->first; | 3095 const SpdySettingsIds id = it->first; |
3098 const uint32 val = it->second.second; | 3096 const uint32_t val = it->second.second; |
3099 switch (id) { | 3097 switch (id) { |
3100 case SETTINGS_CURRENT_CWND: | 3098 case SETTINGS_CURRENT_CWND: |
3101 // Record several different histograms to see if cwnd converges | 3099 // Record several different histograms to see if cwnd converges |
3102 // for larger volumes of data being sent. | 3100 // for larger volumes of data being sent. |
3103 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd", | 3101 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd", |
3104 val, 1, 200, 100); | 3102 val, 1, 200, 100); |
3105 if (total_bytes_received_ > 10 * 1024) { | 3103 if (total_bytes_received_ > 10 * 1024) { |
3106 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd10K", | 3104 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd10K", |
3107 val, 1, 200, 100); | 3105 val, 1, 200, 100); |
3108 if (total_bytes_received_ > 25 * 1024) { | 3106 if (total_bytes_received_ > 25 * 1024) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3178 } | 3176 } |
3179 | 3177 |
3180 void SpdySession::IncreaseSendWindowSize(int delta_window_size) { | 3178 void SpdySession::IncreaseSendWindowSize(int delta_window_size) { |
3181 // We can be called with |in_io_loop_| set if a SpdyBuffer is | 3179 // We can be called with |in_io_loop_| set if a SpdyBuffer is |
3182 // deleted (e.g., a stream is closed due to incoming data). | 3180 // deleted (e.g., a stream is closed due to incoming data). |
3183 | 3181 |
3184 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); | 3182 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); |
3185 DCHECK_GE(delta_window_size, 1); | 3183 DCHECK_GE(delta_window_size, 1); |
3186 | 3184 |
3187 // Check for overflow. | 3185 // Check for overflow. |
3188 int32 max_delta_window_size = kint32max - session_send_window_size_; | 3186 int32_t max_delta_window_size = |
| 3187 std::numeric_limits<int32_t>::max() - session_send_window_size_; |
3189 if (delta_window_size > max_delta_window_size) { | 3188 if (delta_window_size > max_delta_window_size) { |
3190 RecordProtocolErrorHistogram(PROTOCOL_ERROR_INVALID_WINDOW_UPDATE_SIZE); | 3189 RecordProtocolErrorHistogram(PROTOCOL_ERROR_INVALID_WINDOW_UPDATE_SIZE); |
3191 DoDrainSession( | 3190 DoDrainSession( |
3192 ERR_SPDY_PROTOCOL_ERROR, | 3191 ERR_SPDY_PROTOCOL_ERROR, |
3193 "Received WINDOW_UPDATE [delta: " + | 3192 "Received WINDOW_UPDATE [delta: " + |
3194 base::IntToString(delta_window_size) + | 3193 base::IntToString(delta_window_size) + |
3195 "] for session overflows session_send_window_size_ [current: " + | 3194 "] for session overflows session_send_window_size_ [current: " + |
3196 base::IntToString(session_send_window_size_) + "]"); | 3195 base::IntToString(session_send_window_size_) + "]"); |
3197 return; | 3196 return; |
3198 } | 3197 } |
3199 | 3198 |
3200 session_send_window_size_ += delta_window_size; | 3199 session_send_window_size_ += delta_window_size; |
3201 | 3200 |
3202 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_UPDATE_SEND_WINDOW, | 3201 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_UPDATE_SEND_WINDOW, |
3203 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 3202 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
3204 delta_window_size, session_send_window_size_)); | 3203 delta_window_size, session_send_window_size_)); |
3205 | 3204 |
3206 DCHECK(!IsSendStalled()); | 3205 DCHECK(!IsSendStalled()); |
3207 ResumeSendStalledStreams(); | 3206 ResumeSendStalledStreams(); |
3208 } | 3207 } |
3209 | 3208 |
3210 void SpdySession::DecreaseSendWindowSize(int32 delta_window_size) { | 3209 void SpdySession::DecreaseSendWindowSize(int32_t delta_window_size) { |
3211 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); | 3210 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); |
3212 | 3211 |
3213 // We only call this method when sending a frame. Therefore, | 3212 // We only call this method when sending a frame. Therefore, |
3214 // |delta_window_size| should be within the valid frame size range. | 3213 // |delta_window_size| should be within the valid frame size range. |
3215 DCHECK_GE(delta_window_size, 1); | 3214 DCHECK_GE(delta_window_size, 1); |
3216 DCHECK_LE(delta_window_size, kMaxSpdyFrameChunkSize); | 3215 DCHECK_LE(delta_window_size, kMaxSpdyFrameChunkSize); |
3217 | 3216 |
3218 // |send_window_size_| should have been at least |delta_window_size| for | 3217 // |send_window_size_| should have been at least |delta_window_size| for |
3219 // this call to happen. | 3218 // this call to happen. |
3220 DCHECK_GE(session_send_window_size_, delta_window_size); | 3219 DCHECK_GE(session_send_window_size_, delta_window_size); |
3221 | 3220 |
3222 session_send_window_size_ -= delta_window_size; | 3221 session_send_window_size_ -= delta_window_size; |
3223 | 3222 |
3224 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_UPDATE_SEND_WINDOW, | 3223 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_UPDATE_SEND_WINDOW, |
3225 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 3224 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
3226 -delta_window_size, session_send_window_size_)); | 3225 -delta_window_size, session_send_window_size_)); |
3227 } | 3226 } |
3228 | 3227 |
3229 void SpdySession::OnReadBufferConsumed( | 3228 void SpdySession::OnReadBufferConsumed( |
3230 size_t consume_size, | 3229 size_t consume_size, |
3231 SpdyBuffer::ConsumeSource consume_source) { | 3230 SpdyBuffer::ConsumeSource consume_source) { |
3232 // We can be called with |in_io_loop_| set if a read SpdyBuffer is | 3231 // We can be called with |in_io_loop_| set if a read SpdyBuffer is |
3233 // deleted (e.g., discarded by a SpdyReadQueue). | 3232 // deleted (e.g., discarded by a SpdyReadQueue). |
3234 | 3233 |
3235 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); | 3234 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); |
3236 DCHECK_GE(consume_size, 1u); | 3235 DCHECK_GE(consume_size, 1u); |
3237 DCHECK_LE(consume_size, static_cast<size_t>(kint32max)); | 3236 DCHECK_LE(consume_size, |
| 3237 static_cast<size_t>(std::numeric_limits<int32_t>::max())); |
3238 | 3238 |
3239 IncreaseRecvWindowSize(static_cast<int32>(consume_size)); | 3239 IncreaseRecvWindowSize(static_cast<int32_t>(consume_size)); |
3240 } | 3240 } |
3241 | 3241 |
3242 void SpdySession::IncreaseRecvWindowSize(int32 delta_window_size) { | 3242 void SpdySession::IncreaseRecvWindowSize(int32_t delta_window_size) { |
3243 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); | 3243 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); |
3244 DCHECK_GE(session_unacked_recv_window_bytes_, 0); | 3244 DCHECK_GE(session_unacked_recv_window_bytes_, 0); |
3245 DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_); | 3245 DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_); |
3246 DCHECK_GE(delta_window_size, 1); | 3246 DCHECK_GE(delta_window_size, 1); |
3247 // Check for overflow. | 3247 // Check for overflow. |
3248 DCHECK_LE(delta_window_size, kint32max - session_recv_window_size_); | 3248 DCHECK_LE(delta_window_size, |
| 3249 std::numeric_limits<int32_t>::max() - session_recv_window_size_); |
3249 | 3250 |
3250 session_recv_window_size_ += delta_window_size; | 3251 session_recv_window_size_ += delta_window_size; |
3251 net_log_.AddEvent(NetLog::TYPE_HTTP2_STREAM_UPDATE_RECV_WINDOW, | 3252 net_log_.AddEvent(NetLog::TYPE_HTTP2_STREAM_UPDATE_RECV_WINDOW, |
3252 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 3253 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
3253 delta_window_size, session_recv_window_size_)); | 3254 delta_window_size, session_recv_window_size_)); |
3254 | 3255 |
3255 session_unacked_recv_window_bytes_ += delta_window_size; | 3256 session_unacked_recv_window_bytes_ += delta_window_size; |
3256 if (session_unacked_recv_window_bytes_ > session_max_recv_window_size_ / 2) { | 3257 if (session_unacked_recv_window_bytes_ > session_max_recv_window_size_ / 2) { |
3257 SendWindowUpdateFrame(kSessionFlowControlStreamId, | 3258 SendWindowUpdateFrame(kSessionFlowControlStreamId, |
3258 session_unacked_recv_window_bytes_, | 3259 session_unacked_recv_window_bytes_, |
3259 HIGHEST); | 3260 HIGHEST); |
3260 session_unacked_recv_window_bytes_ = 0; | 3261 session_unacked_recv_window_bytes_ = 0; |
3261 } | 3262 } |
3262 } | 3263 } |
3263 | 3264 |
3264 void SpdySession::DecreaseRecvWindowSize(int32 delta_window_size) { | 3265 void SpdySession::DecreaseRecvWindowSize(int32_t delta_window_size) { |
3265 CHECK(in_io_loop_); | 3266 CHECK(in_io_loop_); |
3266 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); | 3267 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); |
3267 DCHECK_GE(delta_window_size, 1); | 3268 DCHECK_GE(delta_window_size, 1); |
3268 | 3269 |
3269 // The receiving window size as the peer knows it is | 3270 // The receiving window size as the peer knows it is |
3270 // |session_recv_window_size_ - session_unacked_recv_window_bytes_|, if more | 3271 // |session_recv_window_size_ - session_unacked_recv_window_bytes_|, if more |
3271 // data are sent by the peer, that means that the receive window is not being | 3272 // data are sent by the peer, that means that the receive window is not being |
3272 // respected. | 3273 // respected. |
3273 if (delta_window_size > | 3274 if (delta_window_size > |
3274 session_recv_window_size_ - session_unacked_recv_window_bytes_) { | 3275 session_recv_window_size_ - session_unacked_recv_window_bytes_) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3331 if (!queue->empty()) { | 3332 if (!queue->empty()) { |
3332 SpdyStreamId stream_id = queue->front(); | 3333 SpdyStreamId stream_id = queue->front(); |
3333 queue->pop_front(); | 3334 queue->pop_front(); |
3334 return stream_id; | 3335 return stream_id; |
3335 } | 3336 } |
3336 } | 3337 } |
3337 return 0; | 3338 return 0; |
3338 } | 3339 } |
3339 | 3340 |
3340 } // namespace net | 3341 } // namespace net |
OLD | NEW |