1 // Copyright 2018 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/socket/connect_job.h"
6
7 #include <set>
8 #include <utility>
9
10 #include "net/base/connection_endpoint_metadata.h"
11 #include "net/base/net_errors.h"
12 #include "net/base/trace_constants.h"
13 #include "net/base/tracing.h"
14 #include "net/dns/public/host_resolver_results.h"
15 #include "net/dns/public/secure_dns_policy.h"
16 #include "net/http/http_auth_controller.h"
17 #include "net/http/http_proxy_connect_job.h"
18 #include "net/log/net_log.h"
19 #include "net/log/net_log_event_type.h"
20 #include "net/socket/client_socket_handle.h"
21 #include "net/socket/socket_tag.h"
22 #include "net/socket/socks_connect_job.h"
23 #include "net/socket/ssl_connect_job.h"
24 #include "net/socket/stream_socket.h"
25 #include "net/socket/transport_connect_job.h"
26 #include "net/traffic_annotation/network_traffic_annotation.h"
27
28 namespace net {
29
CommonConnectJobParams(ClientSocketFactory * client_socket_factory,HostResolver * host_resolver,HttpAuthCache * http_auth_cache,HttpAuthHandlerFactory * http_auth_handler_factory,SpdySessionPool * spdy_session_pool,const quic::ParsedQuicVersionVector * quic_supported_versions,QuicStreamFactory * quic_stream_factory,ProxyDelegate * proxy_delegate,const HttpUserAgentSettings * http_user_agent_settings,SSLClientContext * ssl_client_context,SocketPerformanceWatcherFactory * socket_performance_watcher_factory,NetworkQualityEstimator * network_quality_estimator,NetLog * net_log,WebSocketEndpointLockManager * websocket_endpoint_lock_manager,HttpServerProperties * http_server_properties,const NextProtoVector * alpn_protos,const SSLConfig::ApplicationSettings * application_settings,const bool * ignore_certificate_errors)30 CommonConnectJobParams::CommonConnectJobParams(
31 ClientSocketFactory* client_socket_factory,
32 HostResolver* host_resolver,
33 HttpAuthCache* http_auth_cache,
34 HttpAuthHandlerFactory* http_auth_handler_factory,
35 SpdySessionPool* spdy_session_pool,
36 const quic::ParsedQuicVersionVector* quic_supported_versions,
37 QuicStreamFactory* quic_stream_factory,
38 ProxyDelegate* proxy_delegate,
39 const HttpUserAgentSettings* http_user_agent_settings,
40 SSLClientContext* ssl_client_context,
41 SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
42 NetworkQualityEstimator* network_quality_estimator,
43 NetLog* net_log,
44 WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
45 HttpServerProperties* http_server_properties,
46 const NextProtoVector* alpn_protos,
47 const SSLConfig::ApplicationSettings* application_settings,
48 const bool* ignore_certificate_errors)
49 : client_socket_factory(client_socket_factory),
50 host_resolver(host_resolver),
51 http_auth_cache(http_auth_cache),
52 http_auth_handler_factory(http_auth_handler_factory),
53 spdy_session_pool(spdy_session_pool),
54 quic_supported_versions(quic_supported_versions),
55 quic_stream_factory(quic_stream_factory),
56 proxy_delegate(proxy_delegate),
57 http_user_agent_settings(http_user_agent_settings),
58 ssl_client_context(ssl_client_context),
59 socket_performance_watcher_factory(socket_performance_watcher_factory),
60 network_quality_estimator(network_quality_estimator),
61 net_log(net_log),
62 websocket_endpoint_lock_manager(websocket_endpoint_lock_manager),
63 http_server_properties(http_server_properties),
64 alpn_protos(alpn_protos),
65 application_settings(application_settings),
66 ignore_certificate_errors(ignore_certificate_errors) {}
67
68 CommonConnectJobParams::CommonConnectJobParams(
69 const CommonConnectJobParams& other) = default;
70
71 CommonConnectJobParams::~CommonConnectJobParams() = default;
72
73 CommonConnectJobParams& CommonConnectJobParams::operator=(
74 const CommonConnectJobParams& other) = default;
75
ConnectJob(RequestPriority priority,const SocketTag & socket_tag,base::TimeDelta timeout_duration,const CommonConnectJobParams * common_connect_job_params,Delegate * delegate,const NetLogWithSource * net_log,NetLogSourceType net_log_source_type,NetLogEventType net_log_connect_event_type)76 ConnectJob::ConnectJob(RequestPriority priority,
77 const SocketTag& socket_tag,
78 base::TimeDelta timeout_duration,
79 const CommonConnectJobParams* common_connect_job_params,
80 Delegate* delegate,
81 const NetLogWithSource* net_log,
82 NetLogSourceType net_log_source_type,
83 NetLogEventType net_log_connect_event_type)
84 : timeout_duration_(timeout_duration),
85 priority_(priority),
86 socket_tag_(socket_tag),
87 common_connect_job_params_(common_connect_job_params),
88 delegate_(delegate),
89 top_level_job_(net_log == nullptr),
90 net_log_(net_log
91 ? *net_log
92 : NetLogWithSource::Make(common_connect_job_params->net_log,
93 net_log_source_type)),
94 net_log_connect_event_type_(net_log_connect_event_type) {
95 DCHECK(delegate);
96 if (top_level_job_)
97 net_log_.BeginEvent(NetLogEventType::CONNECT_JOB);
98 }
99
~ConnectJob()100 ConnectJob::~ConnectJob() {
101 // Log end of Connect event if ConnectJob was still in-progress when
102 // destroyed.
103 if (delegate_)
104 LogConnectCompletion(ERR_ABORTED);
105 if (top_level_job_)
106 net_log().EndEvent(NetLogEventType::CONNECT_JOB);
107 }
108
PassSocket()109 std::unique_ptr<StreamSocket> ConnectJob::PassSocket() {
110 return std::move(socket_);
111 }
112
ChangePriority(RequestPriority priority)113 void ConnectJob::ChangePriority(RequestPriority priority) {
114 priority_ = priority;
115 ChangePriorityInternal(priority);
116 }
117
Connect()118 int ConnectJob::Connect() {
119 if (!timeout_duration_.is_zero())
120 timer_.Start(FROM_HERE, timeout_duration_, this, &ConnectJob::OnTimeout);
121
122 LogConnectStart();
123
124 int rv = ConnectInternal();
125
126 if (rv != ERR_IO_PENDING) {
127 LogConnectCompletion(rv);
128 delegate_ = nullptr;
129 }
130
131 return rv;
132 }
133
GetConnectionAttempts() const134 ConnectionAttempts ConnectJob::GetConnectionAttempts() const {
135 // Return empty list by default - used by proxy classes.
136 return ConnectionAttempts();
137 }
138
IsSSLError() const139 bool ConnectJob::IsSSLError() const {
140 return false;
141 }
142
GetCertRequestInfo()143 scoped_refptr<SSLCertRequestInfo> ConnectJob::GetCertRequestInfo() {
144 return nullptr;
145 }
146
set_done_closure(base::OnceClosure done_closure)147 void ConnectJob::set_done_closure(base::OnceClosure done_closure) {
148 done_closure_ = base::ScopedClosureRunner(std::move(done_closure));
149 }
150
151 absl::optional<HostResolverEndpointResult>
GetHostResolverEndpointResult() const152 ConnectJob::GetHostResolverEndpointResult() const {
153 return absl::nullopt;
154 }
155
SetSocket(std::unique_ptr<StreamSocket> socket,absl::optional<std::set<std::string>> dns_aliases)156 void ConnectJob::SetSocket(std::unique_ptr<StreamSocket> socket,
157 absl::optional<std::set<std::string>> dns_aliases) {
158 if (socket) {
159 net_log().AddEventReferencingSource(NetLogEventType::CONNECT_JOB_SET_SOCKET,
160 socket->NetLog().source());
161 if (dns_aliases)
162 socket->SetDnsAliases(std::move(dns_aliases.value()));
163 }
164 socket_ = std::move(socket);
165 }
166
NotifyDelegateOfCompletion(int rv)167 void ConnectJob::NotifyDelegateOfCompletion(int rv) {
168 TRACE_EVENT0(NetTracingCategory(), "ConnectJob::NotifyDelegateOfCompletion");
169 // The delegate will own |this|.
170 Delegate* delegate = delegate_;
171 delegate_ = nullptr;
172
173 LogConnectCompletion(rv);
174 delegate->OnConnectJobComplete(rv, this);
175 }
176
NotifyDelegateOfProxyAuth(const HttpResponseInfo & response,HttpAuthController * auth_controller,base::OnceClosure restart_with_auth_callback)177 void ConnectJob::NotifyDelegateOfProxyAuth(
178 const HttpResponseInfo& response,
179 HttpAuthController* auth_controller,
180 base::OnceClosure restart_with_auth_callback) {
181 delegate_->OnNeedsProxyAuth(response, auth_controller,
182 std::move(restart_with_auth_callback), this);
183 }
184
ResetTimer(base::TimeDelta remaining_time)185 void ConnectJob::ResetTimer(base::TimeDelta remaining_time) {
186 timer_.Stop();
187 if (!remaining_time.is_zero())
188 timer_.Start(FROM_HERE, remaining_time, this, &ConnectJob::OnTimeout);
189 }
190
TimerIsRunning() const191 bool ConnectJob::TimerIsRunning() const {
192 return timer_.IsRunning();
193 }
194
LogConnectStart()195 void ConnectJob::LogConnectStart() {
196 connect_timing_.connect_start = base::TimeTicks::Now();
197 net_log().BeginEvent(net_log_connect_event_type_);
198 }
199
LogConnectCompletion(int net_error)200 void ConnectJob::LogConnectCompletion(int net_error) {
201 connect_timing_.connect_end = base::TimeTicks::Now();
202 net_log().EndEventWithNetErrorCode(net_log_connect_event_type_, net_error);
203 }
204
OnTimeout()205 void ConnectJob::OnTimeout() {
206 // Make sure the socket is NULL before calling into |delegate|.
207 SetSocket(nullptr, absl::nullopt /* dns_aliases */);
208
209 OnTimedOutInternal();
210
211 net_log_.AddEvent(NetLogEventType::CONNECT_JOB_TIMED_OUT);
212
213 NotifyDelegateOfCompletion(ERR_TIMED_OUT);
214 }
215
OnTimedOutInternal()216 void ConnectJob::OnTimedOutInternal() {}
217
218 } // namespace net
219