OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2007 The WebRTC Project Authors. All rights reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include <memory> | |
12 | |
13 #include "webrtc/base/autodetectproxy.h" | |
14 #include "webrtc/base/checks.h" | |
15 #include "webrtc/base/httpcommon.h" | |
16 #include "webrtc/base/httpcommon-inl.h" | |
17 #include "webrtc/base/socketadapters.h" | |
18 #include "webrtc/base/ssladapter.h" | |
19 #include "webrtc/base/sslsocketfactory.h" | |
20 | |
21 namespace rtc { | |
22 | |
23 /////////////////////////////////////////////////////////////////////////////// | |
24 // ProxySocketAdapter | |
25 // TODO: Consider combining AutoDetectProxy and ProxySocketAdapter. I think | |
26 // the socket adapter is the more appropriate idiom for automatic proxy | |
27 // detection. We may or may not want to combine proxydetect.* as well. | |
28 /////////////////////////////////////////////////////////////////////////////// | |
29 | |
30 class ProxySocketAdapter : public AsyncSocketAdapter { | |
31 public: | |
32 ProxySocketAdapter(SslSocketFactory* factory, int family, int type) | |
33 : AsyncSocketAdapter(NULL), factory_(factory), family_(family), | |
34 type_(type), detect_(NULL) { | |
35 } | |
36 ~ProxySocketAdapter() override { | |
37 Close(); | |
38 } | |
39 | |
40 int Connect(const SocketAddress& addr) override { | |
41 RTC_DCHECK(NULL == detect_); | |
42 RTC_DCHECK(NULL == socket_); | |
43 remote_ = addr; | |
44 if (remote_.IsAnyIP() && remote_.hostname().empty()) { | |
45 LOG_F(LS_ERROR) << "Empty address"; | |
46 return SOCKET_ERROR; | |
47 } | |
48 Url<char> url("/", remote_.HostAsURIString(), remote_.port()); | |
49 detect_ = new AutoDetectProxy(factory_->agent_); | |
50 detect_->set_server_url(url.url()); | |
51 detect_->SignalWorkDone.connect(this, | |
52 &ProxySocketAdapter::OnProxyDetectionComplete); | |
53 detect_->Start(); | |
54 return SOCKET_ERROR; | |
55 } | |
56 int GetError() const override { | |
57 if (socket_) { | |
58 return socket_->GetError(); | |
59 } | |
60 return detect_ ? EWOULDBLOCK : EADDRNOTAVAIL; | |
61 } | |
62 int Close() override { | |
63 if (socket_) { | |
64 return socket_->Close(); | |
65 } | |
66 if (detect_) { | |
67 detect_->Destroy(false); | |
68 detect_ = NULL; | |
69 } | |
70 return 0; | |
71 } | |
72 ConnState GetState() const override { | |
73 if (socket_) { | |
74 return socket_->GetState(); | |
75 } | |
76 return detect_ ? CS_CONNECTING : CS_CLOSED; | |
77 } | |
78 | |
79 private: | |
80 // AutoDetectProxy Slots | |
81 void OnProxyDetectionComplete(SignalThread* thread) { | |
82 RTC_DCHECK(detect_ == thread); | |
83 Attach(factory_->CreateProxySocket(detect_->proxy(), family_, type_)); | |
84 detect_->Release(); | |
85 detect_ = NULL; | |
86 if (0 == AsyncSocketAdapter::Connect(remote_)) { | |
87 SignalConnectEvent(this); | |
88 } else if (!IsBlockingError(socket_->GetError())) { | |
89 SignalCloseEvent(this, socket_->GetError()); | |
90 } | |
91 } | |
92 | |
93 SslSocketFactory* factory_; | |
94 int family_; | |
95 int type_; | |
96 SocketAddress remote_; | |
97 AutoDetectProxy* detect_; | |
98 }; | |
99 | |
100 /////////////////////////////////////////////////////////////////////////////// | |
101 // SslSocketFactory | |
102 /////////////////////////////////////////////////////////////////////////////// | |
103 | |
104 SslSocketFactory::SslSocketFactory(SocketFactory* factory, | |
105 const std::string& user_agent) | |
106 : factory_(factory), | |
107 agent_(user_agent), | |
108 autodetect_proxy_(true), | |
109 force_connect_(false), | |
110 logging_level_(LS_VERBOSE), | |
111 binary_mode_(false), | |
112 ignore_bad_cert_(false) { | |
113 } | |
114 | |
115 SslSocketFactory::~SslSocketFactory() = default; | |
116 | |
117 Socket* SslSocketFactory::CreateSocket(int type) { | |
118 return CreateSocket(AF_INET, type); | |
119 } | |
120 | |
121 Socket* SslSocketFactory::CreateSocket(int family, int type) { | |
122 return factory_->CreateSocket(family, type); | |
123 } | |
124 | |
125 AsyncSocket* SslSocketFactory::CreateAsyncSocket(int type) { | |
126 return CreateAsyncSocket(AF_INET, type); | |
127 } | |
128 | |
129 AsyncSocket* SslSocketFactory::CreateAsyncSocket(int family, int type) { | |
130 if (autodetect_proxy_) { | |
131 return new ProxySocketAdapter(this, family, type); | |
132 } else { | |
133 return CreateProxySocket(proxy_, family, type); | |
134 } | |
135 } | |
136 | |
137 | |
138 AsyncSocket* SslSocketFactory::CreateProxySocket(const ProxyInfo& proxy, | |
139 int family, | |
140 int type) { | |
141 AsyncSocket* socket = factory_->CreateAsyncSocket(family, type); | |
142 if (!socket) | |
143 return NULL; | |
144 | |
145 // Binary logging happens at the lowest level | |
146 if (!logging_label_.empty() && binary_mode_) { | |
147 socket = new LoggingSocketAdapter(socket, logging_level_, | |
148 logging_label_.c_str(), binary_mode_); | |
149 } | |
150 | |
151 if (proxy.type) { | |
152 AsyncSocket* proxy_socket = 0; | |
153 if (proxy_.type == PROXY_SOCKS5) { | |
154 proxy_socket = new AsyncSocksProxySocket(socket, proxy.address, | |
155 proxy.username, proxy.password); | |
156 } else { | |
157 // Note: we are trying unknown proxies as HTTPS currently | |
158 AsyncHttpsProxySocket* http_proxy = | |
159 new AsyncHttpsProxySocket(socket, agent_, proxy.address, | |
160 proxy.username, proxy.password); | |
161 http_proxy->SetForceConnect(force_connect_ || !hostname_.empty()); | |
162 proxy_socket = http_proxy; | |
163 } | |
164 if (!proxy_socket) { | |
165 delete socket; | |
166 return NULL; | |
167 } | |
168 socket = proxy_socket; // for our purposes the proxy is now the socket | |
169 } | |
170 | |
171 if (!hostname_.empty()) { | |
172 std::unique_ptr<SSLAdapter> ssl_adapter(SSLAdapter::Create(socket)); | |
173 if (!ssl_adapter) { | |
174 LOG_F(LS_ERROR) << "SSL unavailable"; | |
175 delete socket; | |
176 return NULL; | |
177 } | |
178 | |
179 ssl_adapter->set_ignore_bad_cert(ignore_bad_cert_); | |
180 if (ssl_adapter->StartSSL(hostname_.c_str(), true) != 0) { | |
181 LOG_F(LS_ERROR) << "SSL failed to start."; | |
182 return NULL; | |
183 } | |
184 socket = ssl_adapter.release(); | |
185 } | |
186 | |
187 // Regular logging occurs at the highest level | |
188 if (!logging_label_.empty() && !binary_mode_) { | |
189 socket = new LoggingSocketAdapter(socket, logging_level_, | |
190 logging_label_.c_str(), binary_mode_); | |
191 } | |
192 return socket; | |
193 } | |
194 | |
195 /////////////////////////////////////////////////////////////////////////////// | |
196 | |
197 } // namespace rtc | |
OLD | NEW |