1 // Copyright 2014 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_SOCKET_WEBSOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_ 6 #define NET_SOCKET_WEBSOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_ 7 8 #include <list> 9 #include <map> 10 #include <memory> 11 #include <set> 12 #include <string> 13 #include <utility> 14 15 #include "base/macros.h" 16 #include "base/memory/ref_counted.h" 17 #include "base/memory/weak_ptr.h" 18 #include "base/optional.h" 19 #include "base/time/time.h" 20 #include "base/timer/timer.h" 21 #include "net/base/net_export.h" 22 #include "net/base/proxy_server.h" 23 #include "net/log/net_log_with_source.h" 24 #include "net/socket/client_socket_pool.h" 25 #include "net/socket/connect_job.h" 26 #include "net/socket/ssl_client_socket.h" 27 28 namespace base { 29 namespace trace_event { 30 class ProcessMemoryDump; 31 } 32 } // namespace base 33 34 namespace net { 35 36 struct CommonConnectJobParams; 37 struct NetworkTrafficAnnotationTag; 38 class WebSocketTransportConnectJob; 39 40 class NET_EXPORT_PRIVATE WebSocketTransportClientSocketPool 41 : public ClientSocketPool { 42 public: 43 WebSocketTransportClientSocketPool( 44 int max_sockets, 45 int max_sockets_per_group, 46 const ProxyServer& proxy_server, 47 const CommonConnectJobParams* common_connect_job_params); 48 49 ~WebSocketTransportClientSocketPool() override; 50 51 // Allow another connection to be started to the IPEndPoint that this |handle| 52 // is connected to. Used when the WebSocket handshake completes successfully. 53 // This only works if the socket is connected, however the caller does not 54 // need to explicitly check for this. Instead, ensure that dead sockets are 55 // returned to ReleaseSocket() in a timely fashion. 56 static void UnlockEndpoint( 57 ClientSocketHandle* handle, 58 WebSocketEndpointLockManager* websocket_endpoint_lock_manager); 59 60 // ClientSocketPool implementation. 61 int RequestSocket( 62 const GroupId& group_id, 63 scoped_refptr<SocketParams> params, 64 const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, 65 RequestPriority priority, 66 const SocketTag& socket_tag, 67 RespectLimits respect_limits, 68 ClientSocketHandle* handle, 69 CompletionOnceCallback callback, 70 const ProxyAuthCallback& proxy_auth_callback, 71 const NetLogWithSource& net_log) override; 72 void RequestSockets( 73 const GroupId& group_id, 74 scoped_refptr<SocketParams> params, 75 const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, 76 int num_sockets, 77 const NetLogWithSource& net_log) override; 78 void SetPriority(const GroupId& group_id, 79 ClientSocketHandle* handle, 80 RequestPriority priority) override; 81 void CancelRequest(const GroupId& group_id, 82 ClientSocketHandle* handle, 83 bool cancel_connect_job) override; 84 void ReleaseSocket(const GroupId& group_id, 85 std::unique_ptr<StreamSocket> socket, 86 int64_t generation) override; 87 void FlushWithError(int error, const char* net_log_reason_utf8) override; 88 void CloseIdleSockets(const char* net_log_reason_utf8) override; 89 void CloseIdleSocketsInGroup(const GroupId& group_id, 90 const char* net_log_reason_utf8) override; 91 int IdleSocketCount() const override; 92 size_t IdleSocketCountInGroup(const GroupId& group_id) const override; 93 LoadState GetLoadState(const GroupId& group_id, 94 const ClientSocketHandle* handle) const override; 95 base::Value GetInfoAsValue(const std::string& name, 96 const std::string& type) const override; 97 void DumpMemoryStats( 98 base::trace_event::ProcessMemoryDump* pmd, 99 const std::string& parent_dump_absolute_name) const override; 100 101 // HigherLayeredPool implementation. 102 bool IsStalled() const override; 103 void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override; 104 void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override; 105 106 private: 107 class ConnectJobDelegate : public ConnectJob::Delegate { 108 public: 109 ConnectJobDelegate(WebSocketTransportClientSocketPool* owner, 110 CompletionOnceCallback callback, 111 ClientSocketHandle* socket_handle, 112 const NetLogWithSource& request_net_log); 113 ~ConnectJobDelegate() override; 114 115 // ConnectJob::Delegate implementation 116 void OnConnectJobComplete(int result, ConnectJob* job) override; 117 void OnNeedsProxyAuth(const HttpResponseInfo& response, 118 HttpAuthController* auth_controller, 119 base::OnceClosure restart_with_auth_callback, 120 ConnectJob* job) override; 121 122 // Calls Connect() on |connect_job|, and takes ownership. Returns Connect's 123 // return value. 124 int Connect(std::unique_ptr<ConnectJob> connect_job); 125 release_callback()126 CompletionOnceCallback release_callback() { return std::move(callback_); } connect_job()127 ConnectJob* connect_job() { return connect_job_.get(); } socket_handle()128 ClientSocketHandle* socket_handle() { return socket_handle_; } 129 request_net_log()130 const NetLogWithSource& request_net_log() { return request_net_log_; } 131 const NetLogWithSource& connect_job_net_log(); 132 133 private: 134 WebSocketTransportClientSocketPool* owner_; 135 136 CompletionOnceCallback callback_; 137 std::unique_ptr<ConnectJob> connect_job_; 138 ClientSocketHandle* const socket_handle_; 139 const NetLogWithSource request_net_log_; 140 141 DISALLOW_COPY_AND_ASSIGN(ConnectJobDelegate); 142 }; 143 144 // Store the arguments from a call to RequestSocket() that has stalled so we 145 // can replay it when there are available socket slots. 146 struct StalledRequest { 147 StalledRequest( 148 const GroupId& group_id, 149 const scoped_refptr<SocketParams>& params, 150 const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, 151 RequestPriority priority, 152 ClientSocketHandle* handle, 153 CompletionOnceCallback callback, 154 const ProxyAuthCallback& proxy_auth_callback, 155 const NetLogWithSource& net_log); 156 StalledRequest(StalledRequest&& other); 157 ~StalledRequest(); 158 159 const GroupId group_id; 160 const scoped_refptr<SocketParams> params; 161 const base::Optional<NetworkTrafficAnnotationTag> proxy_annotation_tag; 162 const RequestPriority priority; 163 ClientSocketHandle* const handle; 164 CompletionOnceCallback callback; 165 ProxyAuthCallback proxy_auth_callback; 166 const NetLogWithSource net_log; 167 }; 168 169 typedef std::map<const ClientSocketHandle*, 170 std::unique_ptr<ConnectJobDelegate>> 171 PendingConnectsMap; 172 // This is a list so that we can remove requests from the middle, and also 173 // so that iterators are not invalidated unless the corresponding request is 174 // removed. 175 typedef std::list<StalledRequest> StalledRequestQueue; 176 typedef std::map<const ClientSocketHandle*, StalledRequestQueue::iterator> 177 StalledRequestMap; 178 179 // Tries to hand out the socket connected by |job|. |result| must be (async) 180 // result of WebSocketTransportConnectJob::Connect(). Returns true iff it has 181 // handed out a socket. 182 bool TryHandOutSocket(int result, ConnectJobDelegate* connect_job_delegate); 183 void OnConnectJobComplete(int result, 184 ConnectJobDelegate* connect_job_delegate); 185 void InvokeUserCallbackLater(ClientSocketHandle* handle, 186 CompletionOnceCallback callback, 187 int rv); 188 void InvokeUserCallback(ClientSocketHandle* handle, 189 CompletionOnceCallback callback, 190 int rv); 191 bool ReachedMaxSocketsLimit() const; 192 void HandOutSocket(std::unique_ptr<StreamSocket> socket, 193 const LoadTimingInfo::ConnectTiming& connect_timing, 194 ClientSocketHandle* handle, 195 const NetLogWithSource& net_log); 196 void AddJob(ClientSocketHandle* handle, 197 std::unique_ptr<ConnectJobDelegate> delegate); 198 bool DeleteJob(ClientSocketHandle* handle); 199 const ConnectJob* LookupConnectJob(const ClientSocketHandle* handle) const; 200 void ActivateStalledRequest(); 201 bool DeleteStalledRequest(ClientSocketHandle* handle); 202 203 const ProxyServer proxy_server_; 204 const CommonConnectJobParams* const common_connect_job_params_; 205 std::set<const ClientSocketHandle*> pending_callbacks_; 206 PendingConnectsMap pending_connects_; 207 StalledRequestQueue stalled_request_queue_; 208 StalledRequestMap stalled_request_map_; 209 const int max_sockets_; 210 int handed_out_socket_count_; 211 bool flushing_; 212 213 base::WeakPtrFactory<WebSocketTransportClientSocketPool> weak_factory_{this}; 214 215 DISALLOW_COPY_AND_ASSIGN(WebSocketTransportClientSocketPool); 216 }; 217 218 } // namespace net 219 220 #endif // NET_SOCKET_WEBSOCKET_TRANSPORT_CLIENT_SOCKET_POOL_H_ 221