OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef NET_SPDY_SPDY_SESSION_POOL_H_ | |
6 #define NET_SPDY_SPDY_SESSION_POOL_H_ | |
7 | |
8 #include <stddef.h> | |
9 | |
10 #include <map> | |
11 #include <memory> | |
12 #include <set> | |
13 #include <vector> | |
14 | |
15 #include "base/macros.h" | |
16 #include "base/memory/ref_counted.h" | |
17 #include "base/memory/weak_ptr.h" | |
18 #include "net/base/host_port_pair.h" | |
19 #include "net/base/ip_endpoint.h" | |
20 #include "net/base/net_errors.h" | |
21 #include "net/base/net_export.h" | |
22 #include "net/base/network_change_notifier.h" | |
23 #include "net/cert/cert_database.h" | |
24 #include "net/proxy/proxy_config.h" | |
25 #include "net/proxy/proxy_server.h" | |
26 #include "net/spdy/platform/api/spdy_string.h" | |
27 #include "net/spdy/server_push_delegate.h" | |
28 #include "net/spdy/spdy_protocol.h" | |
29 #include "net/spdy/spdy_session_key.h" | |
30 #include "net/ssl/ssl_config_service.h" | |
31 | |
32 namespace base { | |
33 namespace trace_event { | |
34 class ProcessMemoryDump; | |
35 } | |
36 } | |
37 | |
38 namespace net { | |
39 | |
40 class ClientSocketHandle; | |
41 class HostResolver; | |
42 class HttpServerProperties; | |
43 class NetLogWithSource; | |
44 class ProxyDelegate; | |
45 class SpdySession; | |
46 class TransportSecurityState; | |
47 | |
48 // This is a very simple pool for open SpdySessions. | |
49 class NET_EXPORT SpdySessionPool | |
50 : public NetworkChangeNotifier::IPAddressObserver, | |
51 public SSLConfigService::Observer, | |
52 public CertDatabase::Observer { | |
53 public: | |
54 typedef base::TimeTicks (*TimeFunc)(void); | |
55 | |
56 SpdySessionPool(HostResolver* host_resolver, | |
57 SSLConfigService* ssl_config_service, | |
58 HttpServerProperties* http_server_properties, | |
59 TransportSecurityState* transport_security_state, | |
60 bool enable_ping_based_connection_checking, | |
61 size_t session_max_recv_window_size, | |
62 const SettingsMap& initial_settings, | |
63 SpdySessionPool::TimeFunc time_func, | |
64 ProxyDelegate* proxy_delegate); | |
65 ~SpdySessionPool() override; | |
66 | |
67 // In the functions below, a session is "available" if this pool has | |
68 // a reference to it and there is some SpdySessionKey for which | |
69 // FindAvailableSession() will return it. A session is "unavailable" | |
70 // if this pool has a reference to it but it won't be returned by | |
71 // FindAvailableSession() for any SpdySessionKey; for example, this | |
72 // can happen when a session receives a GOAWAY frame and is still | |
73 // processing existing streams. | |
74 | |
75 // Create a new SPDY session from an existing socket. There must | |
76 // not already be a session for the given key. | |
77 // | |
78 // |is_secure| can be false for testing or when SPDY is configured | |
79 // to work with non-secure sockets. | |
80 // | |
81 // Returns the new SpdySession. Note that the SpdySession begins reading from | |
82 // |connection| on a subsequent event loop iteration, so it may be closed | |
83 // immediately afterwards if the first read of |connection| fails. | |
84 base::WeakPtr<SpdySession> CreateAvailableSessionFromSocket( | |
85 const SpdySessionKey& key, | |
86 std::unique_ptr<ClientSocketHandle> connection, | |
87 const NetLogWithSource& net_log, | |
88 bool is_secure); | |
89 | |
90 // If |url| is not empty and there is a session for |key| that has an | |
91 // unclaimed push stream for |url|, return it. | |
92 // Otherwise if there is an available session for |key|, return it. | |
93 // Otherwise if there is a session to pool to based on IP address: | |
94 // * if |enable_ip_based_pooling == true|, | |
95 // then mark it as available for |key| and return it; | |
96 // * if |enable_ip_based_pooling == false|, | |
97 // then remove it from the available sessions, and return nullptr. | |
98 // Otherwise return nullptr. | |
99 base::WeakPtr<SpdySession> FindAvailableSession( | |
100 const SpdySessionKey& key, | |
101 const GURL& url, | |
102 bool enable_ip_based_pooling, | |
103 const NetLogWithSource& net_log); | |
104 | |
105 // Remove all mappings and aliases for the given session, which must | |
106 // still be available. Except for in tests, this must be called by | |
107 // the given session itself. | |
108 void MakeSessionUnavailable( | |
109 const base::WeakPtr<SpdySession>& available_session); | |
110 | |
111 // Removes an unavailable session from the pool. Except for in | |
112 // tests, this must be called by the given session itself. | |
113 void RemoveUnavailableSession( | |
114 const base::WeakPtr<SpdySession>& unavailable_session); | |
115 | |
116 // Close only the currently existing SpdySessions with |error|. | |
117 // Let any new ones created while this method is running continue to | |
118 // live. | |
119 void CloseCurrentSessions(Error error); | |
120 | |
121 // Close only the currently existing SpdySessions that are idle. | |
122 // Let any new ones created while this method is running continue to | |
123 // live. | |
124 void CloseCurrentIdleSessions(); | |
125 | |
126 // Close all SpdySessions, including any new ones created in the process of | |
127 // closing the current ones. | |
128 void CloseAllSessions(); | |
129 | |
130 // (Un)register a SpdySession with an unclaimed pushed stream for |url|, so | |
131 // that the right SpdySession can be served by FindAvailableSession. | |
132 void RegisterUnclaimedPushedStream(GURL url, | |
133 base::WeakPtr<SpdySession> spdy_session); | |
134 void UnregisterUnclaimedPushedStream(const GURL& url, | |
135 SpdySession* spdy_session); | |
136 | |
137 // Creates a Value summary of the state of the spdy session pool. | |
138 std::unique_ptr<base::Value> SpdySessionPoolInfoToValue() const; | |
139 | |
140 HttpServerProperties* http_server_properties() { | |
141 return http_server_properties_; | |
142 } | |
143 | |
144 void set_server_push_delegate(ServerPushDelegate* push_delegate) { | |
145 push_delegate_ = push_delegate; | |
146 } | |
147 | |
148 // NetworkChangeNotifier::IPAddressObserver methods: | |
149 | |
150 // We flush all idle sessions and release references to the active ones so | |
151 // they won't get re-used. The active ones will either complete successfully | |
152 // or error out due to the IP address change. | |
153 void OnIPAddressChanged() override; | |
154 | |
155 // SSLConfigService::Observer methods: | |
156 | |
157 // We perform the same flushing as described above when SSL settings change. | |
158 void OnSSLConfigChanged() override; | |
159 | |
160 // CertDatabase::Observer methods: | |
161 | |
162 // We perform the same flushing as described above when certificate database | |
163 // is changed. | |
164 void OnCertDBChanged() override; | |
165 | |
166 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd, | |
167 const SpdyString& parent_dump_absolute_name) const; | |
168 | |
169 private: | |
170 friend class SpdySessionPoolPeer; // For testing. | |
171 | |
172 typedef std::set<SpdySession*> SessionSet; | |
173 typedef std::vector<base::WeakPtr<SpdySession> > WeakSessionList; | |
174 typedef std::map<SpdySessionKey, base::WeakPtr<SpdySession> > | |
175 AvailableSessionMap; | |
176 typedef std::map<IPEndPoint, SpdySessionKey> AliasMap; | |
177 typedef std::map<GURL, WeakSessionList> UnclaimedPushedStreamMap; | |
178 | |
179 // Returns true iff |session| is in |available_sessions_|. | |
180 bool IsSessionAvailable(const base::WeakPtr<SpdySession>& session) const; | |
181 | |
182 // Map the given key to the given session. There must not already be | |
183 // a mapping for |key|. | |
184 void MapKeyToAvailableSession(const SpdySessionKey& key, | |
185 const base::WeakPtr<SpdySession>& session); | |
186 | |
187 // Returns an iterator into |available_sessions_| for the given key, | |
188 // which may be equal to |available_sessions_.end()|. | |
189 AvailableSessionMap::iterator LookupAvailableSessionByKey( | |
190 const SpdySessionKey& key); | |
191 | |
192 // Remove the mapping of the given key, which must exist. | |
193 void UnmapKey(const SpdySessionKey& key); | |
194 | |
195 // Remove all aliases for |key| from the aliases table. | |
196 void RemoveAliases(const SpdySessionKey& key); | |
197 | |
198 // Get a copy of the current sessions as a list of WeakPtrs. Used by | |
199 // CloseCurrentSessionsHelper() below. | |
200 WeakSessionList GetCurrentSessions() const; | |
201 | |
202 // Close only the currently existing SpdySessions with |error|. Let | |
203 // any new ones created while this method is running continue to | |
204 // live. If |idle_only| is true only idle sessions are closed. | |
205 void CloseCurrentSessionsHelper(Error error, | |
206 const SpdyString& description, | |
207 bool idle_only); | |
208 | |
209 HttpServerProperties* http_server_properties_; | |
210 | |
211 TransportSecurityState* transport_security_state_; | |
212 | |
213 // The set of all sessions. This is a superset of the sessions in | |
214 // |available_sessions_|. | |
215 // | |
216 // |sessions_| owns all its SpdySession objects. | |
217 SessionSet sessions_; | |
218 | |
219 // This is a map of available sessions by key. A session may appear | |
220 // more than once in this map if it has aliases. | |
221 AvailableSessionMap available_sessions_; | |
222 | |
223 // A map of IPEndPoint aliases for sessions. | |
224 AliasMap aliases_; | |
225 | |
226 // A map of all SpdySessions owned by |this| that have an unclaimed pushed | |
227 // streams for a GURL. Might contain invalid WeakPtr's. | |
228 // A single SpdySession can only have at most one pushed stream for each GURL, | |
229 // but it is possible that multiple SpdySessions have pushed streams for the | |
230 // same GURL. | |
231 UnclaimedPushedStreamMap unclaimed_pushed_streams_; | |
232 | |
233 const scoped_refptr<SSLConfigService> ssl_config_service_; | |
234 HostResolver* const resolver_; | |
235 | |
236 // Defaults to true. May be controlled via SpdySessionPoolPeer for tests. | |
237 bool enable_sending_initial_data_; | |
238 bool enable_ping_based_connection_checking_; | |
239 | |
240 size_t session_max_recv_window_size_; | |
241 | |
242 // Settings that are sent in the initial SETTINGS frame | |
243 // (if |enable_sending_initial_data_| is true), | |
244 // and also control SpdySession parameters like initial receive window size | |
245 // and maximum HPACK dynamic table size. | |
246 const SettingsMap initial_settings_; | |
247 | |
248 TimeFunc time_func_; | |
249 ServerPushDelegate* push_delegate_; | |
250 | |
251 // Determines if a proxy is a trusted SPDY proxy, which is allowed to push | |
252 // resources from origins that are different from those of their associated | |
253 // streams. May be nullptr. | |
254 ProxyDelegate* proxy_delegate_; | |
255 | |
256 DISALLOW_COPY_AND_ASSIGN(SpdySessionPool); | |
257 }; | |
258 | |
259 } // namespace net | |
260 | |
261 #endif // NET_SPDY_SPDY_SESSION_POOL_H_ | |
OLD | NEW |