xref: /aosp_15_r20/external/cronet/net/http/proxy_fallback.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2018 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/http/proxy_fallback.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
8*6777b538SAndroid Build Coastguard Worker #include "net/base/proxy_chain.h"
9*6777b538SAndroid Build Coastguard Worker #include "net/base/proxy_server.h"
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker namespace net {
12*6777b538SAndroid Build Coastguard Worker 
CanFalloverToNextProxy(const ProxyChain & proxy_chain,int error,int * final_error,bool is_for_ip_protection)13*6777b538SAndroid Build Coastguard Worker NET_EXPORT bool CanFalloverToNextProxy(const ProxyChain& proxy_chain,
14*6777b538SAndroid Build Coastguard Worker                                        int error,
15*6777b538SAndroid Build Coastguard Worker                                        int* final_error,
16*6777b538SAndroid Build Coastguard Worker                                        bool is_for_ip_protection) {
17*6777b538SAndroid Build Coastguard Worker   *final_error = error;
18*6777b538SAndroid Build Coastguard Worker   auto proxy_servers = proxy_chain.proxy_servers();
19*6777b538SAndroid Build Coastguard Worker   bool has_quic_proxy = std::any_of(
20*6777b538SAndroid Build Coastguard Worker       proxy_servers.begin(), proxy_servers.end(),
21*6777b538SAndroid Build Coastguard Worker       [](const ProxyServer& proxy_server) { return proxy_server.is_quic(); });
22*6777b538SAndroid Build Coastguard Worker   if (!proxy_chain.is_direct() && has_quic_proxy) {
23*6777b538SAndroid Build Coastguard Worker     // The whole chain should be QUIC.
24*6777b538SAndroid Build Coastguard Worker     for (const auto& proxy_server : proxy_servers) {
25*6777b538SAndroid Build Coastguard Worker       CHECK(proxy_server.is_quic());
26*6777b538SAndroid Build Coastguard Worker     }
27*6777b538SAndroid Build Coastguard Worker     switch (error) {
28*6777b538SAndroid Build Coastguard Worker       case ERR_QUIC_PROTOCOL_ERROR:
29*6777b538SAndroid Build Coastguard Worker       case ERR_QUIC_HANDSHAKE_FAILED:
30*6777b538SAndroid Build Coastguard Worker       case ERR_MSG_TOO_BIG:
31*6777b538SAndroid Build Coastguard Worker         return true;
32*6777b538SAndroid Build Coastguard Worker     }
33*6777b538SAndroid Build Coastguard Worker   }
34*6777b538SAndroid Build Coastguard Worker 
35*6777b538SAndroid Build Coastguard Worker   // TODO(eroman): Split up these error codes across the relevant proxy types.
36*6777b538SAndroid Build Coastguard Worker   //
37*6777b538SAndroid Build Coastguard Worker   // A failure to resolve the hostname or any error related to establishing a
38*6777b538SAndroid Build Coastguard Worker   // TCP connection could be grounds for trying a new proxy configuration.
39*6777b538SAndroid Build Coastguard Worker   //
40*6777b538SAndroid Build Coastguard Worker   // Why do this when a hostname cannot be resolved?  Some URLs only make sense
41*6777b538SAndroid Build Coastguard Worker   // to proxy servers.  The hostname in those URLs might fail to resolve if we
42*6777b538SAndroid Build Coastguard Worker   // are still using a non-proxy config.  We need to check if a proxy config
43*6777b538SAndroid Build Coastguard Worker   // now exists that corresponds to a proxy server that could load the URL.
44*6777b538SAndroid Build Coastguard Worker 
45*6777b538SAndroid Build Coastguard Worker   switch (error) {
46*6777b538SAndroid Build Coastguard Worker     case ERR_PROXY_CONNECTION_FAILED:
47*6777b538SAndroid Build Coastguard Worker     case ERR_NAME_NOT_RESOLVED:
48*6777b538SAndroid Build Coastguard Worker     case ERR_INTERNET_DISCONNECTED:
49*6777b538SAndroid Build Coastguard Worker     case ERR_ADDRESS_UNREACHABLE:
50*6777b538SAndroid Build Coastguard Worker     case ERR_CONNECTION_CLOSED:
51*6777b538SAndroid Build Coastguard Worker     case ERR_CONNECTION_TIMED_OUT:
52*6777b538SAndroid Build Coastguard Worker     case ERR_CONNECTION_RESET:
53*6777b538SAndroid Build Coastguard Worker     case ERR_CONNECTION_REFUSED:
54*6777b538SAndroid Build Coastguard Worker     case ERR_CONNECTION_ABORTED:
55*6777b538SAndroid Build Coastguard Worker     case ERR_TIMED_OUT:
56*6777b538SAndroid Build Coastguard Worker     case ERR_SOCKS_CONNECTION_FAILED:
57*6777b538SAndroid Build Coastguard Worker     // ERR_PROXY_CERTIFICATE_INVALID can happen in the case of trying to talk to
58*6777b538SAndroid Build Coastguard Worker     // a proxy using SSL, and ending up talking to a captive portal that
59*6777b538SAndroid Build Coastguard Worker     // supports SSL instead.
60*6777b538SAndroid Build Coastguard Worker     case ERR_PROXY_CERTIFICATE_INVALID:
61*6777b538SAndroid Build Coastguard Worker     // ERR_SSL_PROTOCOL_ERROR can happen when trying to talk SSL to a non-SSL
62*6777b538SAndroid Build Coastguard Worker     // server (like a captive portal).
63*6777b538SAndroid Build Coastguard Worker     case ERR_SSL_PROTOCOL_ERROR:
64*6777b538SAndroid Build Coastguard Worker       return true;
65*6777b538SAndroid Build Coastguard Worker 
66*6777b538SAndroid Build Coastguard Worker     case ERR_SOCKS_CONNECTION_HOST_UNREACHABLE:
67*6777b538SAndroid Build Coastguard Worker       // Remap the SOCKS-specific "host unreachable" error to a more
68*6777b538SAndroid Build Coastguard Worker       // generic error code (this way consumers like the link doctor
69*6777b538SAndroid Build Coastguard Worker       // know to substitute their error page).
70*6777b538SAndroid Build Coastguard Worker       //
71*6777b538SAndroid Build Coastguard Worker       // Note that if the host resolving was done by the SOCKS5 proxy, we can't
72*6777b538SAndroid Build Coastguard Worker       // differentiate between a proxy-side "host not found" versus a proxy-side
73*6777b538SAndroid Build Coastguard Worker       // "address unreachable" error, and will report both of these failures as
74*6777b538SAndroid Build Coastguard Worker       // ERR_ADDRESS_UNREACHABLE.
75*6777b538SAndroid Build Coastguard Worker       *final_error = ERR_ADDRESS_UNREACHABLE;
76*6777b538SAndroid Build Coastguard Worker       return false;
77*6777b538SAndroid Build Coastguard Worker 
78*6777b538SAndroid Build Coastguard Worker     case ERR_TUNNEL_CONNECTION_FAILED:
79*6777b538SAndroid Build Coastguard Worker       // A failure while establishing a tunnel to the proxy is only considered
80*6777b538SAndroid Build Coastguard Worker       // grounds for fallback when connecting to an IP Protection proxy. Other
81*6777b538SAndroid Build Coastguard Worker       // browsers similarly don't fallback, and some client's PAC configurations
82*6777b538SAndroid Build Coastguard Worker       // rely on this for some degree of content blocking. See
83*6777b538SAndroid Build Coastguard Worker       // https://crbug.com/680837 for details.
84*6777b538SAndroid Build Coastguard Worker       return is_for_ip_protection;
85*6777b538SAndroid Build Coastguard Worker   }
86*6777b538SAndroid Build Coastguard Worker   return false;
87*6777b538SAndroid Build Coastguard Worker }
88*6777b538SAndroid Build Coastguard Worker 
89*6777b538SAndroid Build Coastguard Worker }  // namespace net
90