client_socket_handle.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  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. #ifndef NET_SOCKET_CLIENT_SOCKET_HANDLE_H_
  5. #define NET_SOCKET_CLIENT_SOCKET_HANDLE_H_
  6. #include <memory>
  7. #include <utility>
  8. #include "base/bind.h"
  9. #include "base/check.h"
  10. #include "base/memory/raw_ptr.h"
  11. #include "base/memory/ref_counted.h"
  12. #include "base/time/time.h"
  13. #include "net/base/ip_endpoint.h"
  14. #include "net/base/load_states.h"
  15. #include "net/base/load_timing_info.h"
  16. #include "net/base/net_errors.h"
  17. #include "net/base/net_export.h"
  18. #include "net/base/request_priority.h"
  19. #include "net/dns/public/resolve_error_info.h"
  20. #include "net/log/net_log_source.h"
  21. #include "net/log/net_log_with_source.h"
  22. #include "net/socket/client_socket_pool.h"
  23. #include "net/socket/connection_attempts.h"
  24. #include "net/socket/stream_socket.h"
  25. #include "net/ssl/ssl_cert_request_info.h"
  26. #include "third_party/abseil-cpp/absl/types/optional.h"
  27. namespace net {
  28. class ConnectJob;
  29. struct NetworkTrafficAnnotationTag;
  30. class SocketTag;
  31. // A container for a StreamSocket.
  32. //
  33. // The handle's |group_id| uniquely identifies the origin and type of the
  34. // connection. It is used by the ClientSocketPool to group similar connected
  35. // client socket objects.
  36. //
  37. class NET_EXPORT ClientSocketHandle {
  38. public:
  39. enum SocketReuseType {
  40. UNUSED = 0, // unused socket that just finished connecting
  41. UNUSED_IDLE, // unused socket that has been idle for awhile
  42. REUSED_IDLE, // previously used socket
  43. NUM_TYPES,
  44. };
  45. ClientSocketHandle();
  46. ClientSocketHandle(const ClientSocketHandle&) = delete;
  47. ClientSocketHandle& operator=(const ClientSocketHandle&) = delete;
  48. ~ClientSocketHandle();
  49. // Initializes a ClientSocketHandle object, which involves talking to the
  50. // ClientSocketPool to obtain a connected socket, possibly reusing one. This
  51. // method returns either OK or ERR_IO_PENDING. On ERR_IO_PENDING, |priority|
  52. // is used to determine the placement in ClientSocketPool's wait list.
  53. // If |respect_limits| is DISABLED, will bypass the wait list, but |priority|
  54. // must also be HIGHEST, if set.
  55. //
  56. // If this method succeeds, then the socket member will be set to an existing
  57. // connected socket if an existing connected socket was available to reuse,
  58. // otherwise it will be set to a new connected socket. Consumers can then
  59. // call is_reused() to see if the socket was reused. If not reusing an
  60. // existing socket, ClientSocketPool may need to establish a new
  61. // connection using |socket_params|.
  62. //
  63. // This method returns ERR_IO_PENDING if it cannot complete synchronously, in
  64. // which case the consumer will be notified of completion via |callback|.
  65. //
  66. // If the pool was not able to reuse an existing socket, the new socket
  67. // may report a recoverable error. In this case, the return value will
  68. // indicate an error and the socket member will be set. If it is determined
  69. // that the error is not recoverable, the Disconnect method should be used
  70. // on the socket, so that it does not get reused.
  71. //
  72. // A non-recoverable error may set additional state in the ClientSocketHandle
  73. // to allow the caller to determine what went wrong.
  74. //
  75. // Init may be called multiple times.
  76. //
  77. // Profiling information for the request is saved to |net_log| if non-NULL.
  78. int Init(
  79. const ClientSocketPool::GroupId& group_id,
  80. scoped_refptr<ClientSocketPool::SocketParams> socket_params,
  81. const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
  82. RequestPriority priority,
  83. const SocketTag& socket_tag,
  84. ClientSocketPool::RespectLimits respect_limits,
  85. CompletionOnceCallback callback,
  86. const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback,
  87. ClientSocketPool* pool,
  88. const NetLogWithSource& net_log);
  89. // Changes the priority of the ClientSocketHandle to the passed value.
  90. // This function is a no-op if |priority| is the same as the current
  91. // priority, of if Init() has not been called since the last time
  92. // the ClientSocketHandle was reset.
  93. void SetPriority(RequestPriority priority);
  94. // An initialized handle can be reset, which causes it to return to the
  95. // un-initialized state. This releases the underlying socket, which in the
  96. // case of a socket that still has an established connection, indicates that
  97. // the socket may be kept alive for use by a subsequent ClientSocketHandle.
  98. //
  99. // NOTE: To prevent the socket from being kept alive, be sure to call its
  100. // Disconnect method. This will result in the ClientSocketPool deleting the
  101. // StreamSocket.
  102. void Reset();
  103. // Like Reset(), but also closes the socket (if there is one) and cancels any
  104. // pending attempt to establish a connection, if the connection attempt is
  105. // still ongoing.
  106. void ResetAndCloseSocket();
  107. // Used after Init() is called, but before the ClientSocketPool has
  108. // initialized the ClientSocketHandle.
  109. LoadState GetLoadState() const;
  110. bool IsPoolStalled() const;
  111. // Adds a higher layered pool on top of the socket pool that |socket_| belongs
  112. // to. At most one higher layered pool can be added to a
  113. // ClientSocketHandle at a time. On destruction or reset, automatically
  114. // removes the higher pool if RemoveHigherLayeredPool has not been called.
  115. void AddHigherLayeredPool(HigherLayeredPool* higher_pool);
  116. // Removes a higher layered pool from the socket pool that |socket_| belongs
  117. // to. |higher_pool| must have been added by the above function.
  118. void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool);
  119. // Closes idle sockets that are in the same group with |this|.
  120. void CloseIdleSocketsInGroup(const char* net_log_reason_utf8);
  121. // Returns true when Init() has completed successfully.
  122. bool is_initialized() const { return is_initialized_; }
  123. // Sets the portion of LoadTimingInfo related to connection establishment, and
  124. // the socket id. |is_reused| is needed because the handle may not have full
  125. // reuse information. |load_timing_info| must have all default values when
  126. // called. Returns false and makes no changes to |load_timing_info| when
  127. // |socket_| is NULL.
  128. bool GetLoadTimingInfo(bool is_reused,
  129. LoadTimingInfo* load_timing_info) const;
  130. // Used by ClientSocketPool to initialize the ClientSocketHandle.
  131. //
  132. // SetSocket() may also be used if this handle is used as simply for
  133. // socket storage (e.g., http://crbug.com/37810).
  134. void SetSocket(std::unique_ptr<StreamSocket> s);
  135. // Populates several fields of |this| with error-related information from the
  136. // provided completed ConnectJob. Should only be called on ConnectJob failure.
  137. void SetAdditionalErrorState(ConnectJob* connect_job);
  138. void set_reuse_type(SocketReuseType reuse_type) { reuse_type_ = reuse_type; }
  139. void set_idle_time(base::TimeDelta idle_time) { idle_time_ = idle_time; }
  140. void set_group_generation(int64_t group_generation) {
  141. group_generation_ = group_generation;
  142. }
  143. void set_is_ssl_error(bool is_ssl_error) { is_ssl_error_ = is_ssl_error; }
  144. void set_ssl_cert_request_info(
  145. scoped_refptr<SSLCertRequestInfo> ssl_cert_request_info) {
  146. ssl_cert_request_info_ = std::move(ssl_cert_request_info);
  147. }
  148. void set_connection_attempts(const ConnectionAttempts& attempts) {
  149. connection_attempts_ = attempts;
  150. }
  151. ResolveErrorInfo resolve_error_info() const { return resolve_error_info_; }
  152. // Only valid if there is no |socket_|.
  153. bool is_ssl_error() const {
  154. DCHECK(!socket_);
  155. return is_ssl_error_;
  156. }
  157. // On an ERR_SSL_CLIENT_AUTH_CERT_NEEDED error, the |cert_request_info| field
  158. // is set.
  159. scoped_refptr<SSLCertRequestInfo> ssl_cert_request_info() const {
  160. return ssl_cert_request_info_;
  161. }
  162. // If the connection failed, returns the connection attempts made.
  163. const ConnectionAttempts& connection_attempts() {
  164. return connection_attempts_;
  165. }
  166. StreamSocket* socket() { return socket_.get(); }
  167. // SetSocket() must be called with a new socket before this handle
  168. // is destroyed if is_initialized() is true.
  169. std::unique_ptr<StreamSocket> PassSocket();
  170. // These may only be used if is_initialized() is true.
  171. const ClientSocketPool::GroupId& group_id() const { return group_id_; }
  172. int64_t group_generation() const { return group_generation_; }
  173. bool is_reused() const { return reuse_type_ == REUSED_IDLE; }
  174. base::TimeDelta idle_time() const { return idle_time_; }
  175. SocketReuseType reuse_type() const { return reuse_type_; }
  176. const LoadTimingInfo::ConnectTiming& connect_timing() const {
  177. return connect_timing_;
  178. }
  179. void set_connect_timing(const LoadTimingInfo::ConnectTiming& connect_timing) {
  180. connect_timing_ = connect_timing;
  181. }
  182. private:
  183. // Called on asynchronous completion of an Init() request.
  184. void OnIOComplete(int result);
  185. // Called on completion (both asynchronous & synchronous) of an Init()
  186. // request.
  187. void HandleInitCompletion(int result);
  188. // Resets the state of the ClientSocketHandle. |cancel| indicates whether or
  189. // not to try to cancel the request with the ClientSocketPool. Does not
  190. // reset the supplemental error state. |cancel_connect_job| indicates whether
  191. // a pending ConnectJob, if there is one in the SocketPool, should be
  192. // cancelled in addition to cancelling the request. It may only be true if
  193. // |cancel| is also true.
  194. void ResetInternal(bool cancel, bool cancel_connect_job);
  195. // Resets the supplemental error state.
  196. void ResetErrorState();
  197. bool is_initialized_ = false;
  198. raw_ptr<ClientSocketPool> pool_ = nullptr;
  199. raw_ptr<HigherLayeredPool> higher_pool_ = nullptr;
  200. std::unique_ptr<StreamSocket> socket_;
  201. ClientSocketPool::GroupId group_id_;
  202. SocketReuseType reuse_type_ = ClientSocketHandle::UNUSED;
  203. CompletionOnceCallback callback_;
  204. base::TimeDelta idle_time_;
  205. // See ClientSocketPool::ReleaseSocket() for an explanation.
  206. int64_t group_generation_ = -1;
  207. ResolveErrorInfo resolve_error_info_;
  208. bool is_ssl_error_ = false;
  209. scoped_refptr<SSLCertRequestInfo> ssl_cert_request_info_;
  210. std::vector<ConnectionAttempt> connection_attempts_;
  211. NetLogSource requesting_source_;
  212. // Timing information is set when a connection is successfully established.
  213. LoadTimingInfo::ConnectTiming connect_timing_;
  214. };
  215. } // namespace net
  216. #endif // NET_SOCKET_CLIENT_SOCKET_HANDLE_H_