| 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 <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1395 NetLog::TYPE_SPDY_SESSION_RECV_DATA, | 1395 NetLog::TYPE_SPDY_SESSION_RECV_DATA, |
| 1396 base::Bind(&NetLogSpdyDataCallback, stream_id, len, fin)); | 1396 base::Bind(&NetLogSpdyDataCallback, stream_id, len, fin)); |
| 1397 } | 1397 } |
| 1398 | 1398 |
| 1399 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); | 1399 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); |
| 1400 | 1400 |
| 1401 // By the time data comes in, the stream may already be inactive. | 1401 // By the time data comes in, the stream may already be inactive. |
| 1402 if (it == active_streams_.end()) | 1402 if (it == active_streams_.end()) |
| 1403 return; | 1403 return; |
| 1404 | 1404 |
| 1405 // Only decrease the window size for data for active streams. | |
| 1406 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION && len > 0) | |
| 1407 DecreaseRecvWindowSize(static_cast<int32>(len)); | |
| 1408 | |
| 1409 scoped_ptr<SpdyBuffer> buffer; | 1405 scoped_ptr<SpdyBuffer> buffer; |
| 1410 if (data) { | 1406 if (data) { |
| 1411 DCHECK_GT(len, 0u); | 1407 DCHECK_GT(len, 0u); |
| 1412 buffer.reset(new SpdyBuffer(data, len)); | 1408 buffer.reset(new SpdyBuffer(data, len)); |
| 1409 |
| 1410 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { |
| 1411 DecreaseRecvWindowSize(static_cast<int32>(len)); |
| 1412 buffer->AddConsumeCallback( |
| 1413 base::Bind(&SpdySession::IncreaseRecvWindowSize, |
| 1414 weak_factory_.GetWeakPtr())); |
| 1415 } |
| 1413 } else { | 1416 } else { |
| 1414 DCHECK_EQ(len, 0u); | 1417 DCHECK_EQ(len, 0u); |
| 1415 } | 1418 } |
| 1416 it->second->OnDataReceived(buffer.Pass()); | 1419 it->second->OnDataReceived(buffer.Pass()); |
| 1417 } | 1420 } |
| 1418 | 1421 |
| 1419 void SpdySession::OnSetting(SpdySettingsIds id, | 1422 void SpdySession::OnSetting(SpdySettingsIds id, |
| 1420 uint8 flags, | 1423 uint8 flags, |
| 1421 uint32 value) { | 1424 uint32 value) { |
| 1422 HandleSetting(id, value); | 1425 HandleSetting(id, value); |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1798 | 1801 |
| 1799 void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id, | 1802 void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id, |
| 1800 uint32 delta_window_size) { | 1803 uint32 delta_window_size) { |
| 1801 CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); | 1804 CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); |
| 1802 CHECK(IsStreamActive(stream_id)); | 1805 CHECK(IsStreamActive(stream_id)); |
| 1803 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 1806 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
| 1804 CHECK_EQ(stream->stream_id(), stream_id); | 1807 CHECK_EQ(stream->stream_id(), stream_id); |
| 1805 SendWindowUpdateFrame(stream_id, delta_window_size, stream->priority()); | 1808 SendWindowUpdateFrame(stream_id, delta_window_size, stream->priority()); |
| 1806 } | 1809 } |
| 1807 | 1810 |
| 1808 void SpdySession::IncreaseRecvWindowSize(int32 delta_window_size) { | |
| 1809 if (flow_control_state_ < FLOW_CONTROL_STREAM_AND_SESSION) | |
| 1810 return; | |
| 1811 | |
| 1812 DCHECK_GE(session_unacked_recv_window_bytes_, 0); | |
| 1813 DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_); | |
| 1814 DCHECK_GE(delta_window_size, 1); | |
| 1815 // Check for overflow. | |
| 1816 DCHECK_LE(delta_window_size, kint32max - session_recv_window_size_); | |
| 1817 | |
| 1818 session_recv_window_size_ += delta_window_size; | |
| 1819 net_log_.AddEvent( | |
| 1820 NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW, | |
| 1821 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | |
| 1822 delta_window_size, session_recv_window_size_)); | |
| 1823 | |
| 1824 session_unacked_recv_window_bytes_ += delta_window_size; | |
| 1825 if (session_unacked_recv_window_bytes_ > kSpdySessionInitialWindowSize / 2) { | |
| 1826 SendWindowUpdateFrame(kSessionFlowControlStreamId, | |
| 1827 session_unacked_recv_window_bytes_, | |
| 1828 HIGHEST); | |
| 1829 session_unacked_recv_window_bytes_ = 0; | |
| 1830 } | |
| 1831 } | |
| 1832 | |
| 1833 // Given a cwnd that we would have sent to the server, modify it based on the | 1811 // Given a cwnd that we would have sent to the server, modify it based on the |
| 1834 // field trial policy. | 1812 // field trial policy. |
| 1835 uint32 ApplyCwndFieldTrialPolicy(int cwnd) { | 1813 uint32 ApplyCwndFieldTrialPolicy(int cwnd) { |
| 1836 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd"); | 1814 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd"); |
| 1837 if (!trial) { | 1815 if (!trial) { |
| 1838 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList"; | 1816 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList"; |
| 1839 return cwnd; | 1817 return cwnd; |
| 1840 } | 1818 } |
| 1841 if (trial->group_name() == "cwnd10") | 1819 if (trial->group_name() == "cwnd10") |
| 1842 return 10; | 1820 return 10; |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2273 DCHECK_GE(session_send_window_size_, delta_window_size); | 2251 DCHECK_GE(session_send_window_size_, delta_window_size); |
| 2274 | 2252 |
| 2275 session_send_window_size_ -= delta_window_size; | 2253 session_send_window_size_ -= delta_window_size; |
| 2276 | 2254 |
| 2277 net_log_.AddEvent( | 2255 net_log_.AddEvent( |
| 2278 NetLog::TYPE_SPDY_SESSION_UPDATE_SEND_WINDOW, | 2256 NetLog::TYPE_SPDY_SESSION_UPDATE_SEND_WINDOW, |
| 2279 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 2257 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
| 2280 -delta_window_size, session_send_window_size_)); | 2258 -delta_window_size, session_send_window_size_)); |
| 2281 } | 2259 } |
| 2282 | 2260 |
| 2261 void SpdySession::IncreaseRecvWindowSize(size_t delta_window_size) { |
| 2262 if (flow_control_state_ < FLOW_CONTROL_STREAM_AND_SESSION) |
| 2263 return; |
| 2264 |
| 2265 DCHECK_GE(session_unacked_recv_window_bytes_, 0); |
| 2266 DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_); |
| 2267 DCHECK_GE(delta_window_size, 1u); |
| 2268 // Check for overflow. |
| 2269 DCHECK_LE(delta_window_size, |
| 2270 static_cast<size_t>(kint32max - session_recv_window_size_)); |
| 2271 |
| 2272 session_recv_window_size_ += delta_window_size; |
| 2273 net_log_.AddEvent( |
| 2274 NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW, |
| 2275 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
| 2276 delta_window_size, session_recv_window_size_)); |
| 2277 |
| 2278 session_unacked_recv_window_bytes_ += delta_window_size; |
| 2279 if (session_unacked_recv_window_bytes_ > kSpdySessionInitialWindowSize / 2) { |
| 2280 SendWindowUpdateFrame(kSessionFlowControlStreamId, |
| 2281 session_unacked_recv_window_bytes_, |
| 2282 HIGHEST); |
| 2283 session_unacked_recv_window_bytes_ = 0; |
| 2284 } |
| 2285 } |
| 2286 |
| 2283 void SpdySession::DecreaseRecvWindowSize(int32 delta_window_size) { | 2287 void SpdySession::DecreaseRecvWindowSize(int32 delta_window_size) { |
| 2284 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); | 2288 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); |
| 2285 DCHECK_GE(delta_window_size, 1); | 2289 DCHECK_GE(delta_window_size, 1); |
| 2286 | 2290 |
| 2287 // |delta_window_size| should never cause | 2291 // |delta_window_size| should never cause |
| 2288 // |session_recv_window_size_| to go negative. If we do, it's a | 2292 // |session_recv_window_size_| to go negative. If we do, it's a |
| 2289 // client-side bug. | 2293 // client-side bug. |
| 2290 if (delta_window_size > session_recv_window_size_) { | 2294 if (delta_window_size > session_recv_window_size_) { |
| 2291 NOTREACHED() << "Received session WINDOW_UPDATE with an " | 2295 NOTREACHED() << "Received session WINDOW_UPDATE with an " |
| 2292 << "invalid delta_window_size " << delta_window_size; | 2296 << "invalid delta_window_size " << delta_window_size; |
| 2293 // TODO(akalin): Figure out whether we should instead send a | 2297 // TODO(akalin): Figure out whether we should instead send a |
| 2294 // GOAWAY and close the connection here. | 2298 // GOAWAY and close the connection here. |
| 2295 return; | 2299 return; |
| 2296 } | 2300 } |
| 2297 | 2301 |
| 2298 session_recv_window_size_ -= delta_window_size; | 2302 session_recv_window_size_ -= delta_window_size; |
| 2299 net_log_.AddEvent( | 2303 net_log_.AddEvent( |
| 2300 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW, | 2304 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW, |
| 2301 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 2305 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
| 2302 -delta_window_size, session_recv_window_size_)); | 2306 -delta_window_size, session_recv_window_size_)); |
| 2303 } | 2307 } |
| 2304 | 2308 |
| 2305 } // namespace net | 2309 } // namespace net |
| OLD | NEW |