• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 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/tcp_stream_attempt.h"
6 
7 #include <memory>
8 #include <string_view>
9 
10 #include "base/time/time.h"
11 #include "base/timer/timer.h"
12 #include "base/values.h"
13 #include "net/base/address_list.h"
14 #include "net/base/net_errors.h"
15 #include "net/socket/client_socket_factory.h"
16 #include "net/socket/socket_performance_watcher.h"
17 #include "net/socket/socket_performance_watcher_factory.h"
18 #include "net/socket/transport_client_socket.h"
19 
20 namespace net {
21 
22 // static
StateToString(State state)23 std::string_view TcpStreamAttempt::StateToString(State state) {
24   switch (state) {
25     case State::kNone:
26       return "None";
27     case State::kConnecting:
28       return "Connecting";
29   }
30 }
31 
TcpStreamAttempt(const StreamAttemptParams * params,IPEndPoint ip_endpoint,const NetLogWithSource * net_log)32 TcpStreamAttempt::TcpStreamAttempt(const StreamAttemptParams* params,
33                                    IPEndPoint ip_endpoint,
34                                    const NetLogWithSource* net_log)
35     : StreamAttempt(params,
36                     ip_endpoint,
37                     NetLogSourceType::TCP_STREAM_ATTEMPT,
38                     NetLogEventType::TCP_STREAM_ATTEMPT_ALIVE,
39                     net_log) {}
40 
41 TcpStreamAttempt::~TcpStreamAttempt() = default;
42 
GetLoadState() const43 LoadState TcpStreamAttempt::GetLoadState() const {
44   switch (next_state_) {
45     case State::kNone:
46       return LOAD_STATE_IDLE;
47     case State::kConnecting:
48       return LOAD_STATE_CONNECTING;
49   }
50 }
51 
GetInfoAsValue() const52 base::Value::Dict TcpStreamAttempt::GetInfoAsValue() const {
53   base::Value::Dict dict;
54   dict.Set("next_state", StateToString(next_state_));
55   return dict;
56 }
57 
StartInternal()58 int TcpStreamAttempt::StartInternal() {
59   next_state_ = State::kConnecting;
60 
61   std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher;
62   if (params().socket_performance_watcher_factory) {
63     socket_performance_watcher =
64         params()
65             .socket_performance_watcher_factory->CreateSocketPerformanceWatcher(
66                 SocketPerformanceWatcherFactory::PROTOCOL_TCP,
67                 ip_endpoint().address());
68   }
69 
70   std::unique_ptr<TransportClientSocket> stream_socket =
71       params().client_socket_factory->CreateTransportClientSocket(
72           AddressList(ip_endpoint()), std::move(socket_performance_watcher),
73           params().network_quality_estimator, net_log().net_log(),
74           net_log().source());
75 
76   TransportClientSocket* socket_ptr = stream_socket.get();
77   SetStreamSocket(std::move(stream_socket));
78 
79   mutable_connect_timing().connect_start = base::TimeTicks::Now();
80   CHECK(!timeout_timer_.IsRunning());
81   timeout_timer_.Start(
82       FROM_HERE, kTcpHandshakeTimeout,
83       base::BindOnce(&TcpStreamAttempt::OnTimeout, base::Unretained(this)));
84 
85   net_log().AddEventReferencingSource(
86       NetLogEventType::TCP_STREAM_ATTEMPT_CONNECT,
87       socket_ptr->NetLog().source());
88   int rv = socket_ptr->Connect(
89       base::BindOnce(&TcpStreamAttempt::OnIOComplete, base::Unretained(this)));
90   if (rv != ERR_IO_PENDING) {
91     HandleCompletion();
92   }
93   return rv;
94 }
95 
GetNetLogStartParams()96 base::Value::Dict TcpStreamAttempt::GetNetLogStartParams() {
97   base::Value::Dict dict;
98   dict.Set("ip_endpoint", ip_endpoint().ToString());
99   return dict;
100 }
101 
HandleCompletion()102 void TcpStreamAttempt::HandleCompletion() {
103   next_state_ = State::kNone;
104   timeout_timer_.Stop();
105   mutable_connect_timing().connect_end = base::TimeTicks::Now();
106 }
107 
OnIOComplete(int rv)108 void TcpStreamAttempt::OnIOComplete(int rv) {
109   CHECK_NE(rv, ERR_IO_PENDING);
110   HandleCompletion();
111   NotifyOfCompletion(rv);
112 }
113 
OnTimeout()114 void TcpStreamAttempt::OnTimeout() {
115   SetStreamSocket(nullptr);
116   // TODO(bashi): The error code should be ERR_CONNECTION_TIMED_OUT but use
117   // ERR_TIMED_OUT for consistency with ConnectJobs.
118   OnIOComplete(ERR_TIMED_OUT);
119 }
120 
121 }  // namespace net
122