• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "webrtc/base/autodetectproxy.h"
12 #include "webrtc/base/httpcommon.h"
13 #include "webrtc/base/httpcommon-inl.h"
14 #include "webrtc/base/socketadapters.h"
15 #include "webrtc/base/ssladapter.h"
16 #include "webrtc/base/sslsocketfactory.h"
17 
18 namespace rtc {
19 
20 ///////////////////////////////////////////////////////////////////////////////
21 // ProxySocketAdapter
22 // TODO: Consider combining AutoDetectProxy and ProxySocketAdapter.  I think
23 // the socket adapter is the more appropriate idiom for automatic proxy
24 // detection.  We may or may not want to combine proxydetect.* as well.
25 ///////////////////////////////////////////////////////////////////////////////
26 
27 class ProxySocketAdapter : public AsyncSocketAdapter {
28  public:
ProxySocketAdapter(SslSocketFactory * factory,int family,int type)29   ProxySocketAdapter(SslSocketFactory* factory, int family, int type)
30       : AsyncSocketAdapter(NULL), factory_(factory), family_(family),
31         type_(type), detect_(NULL) {
32   }
~ProxySocketAdapter()33   virtual ~ProxySocketAdapter() {
34     Close();
35   }
36 
Connect(const SocketAddress & addr)37   virtual int Connect(const SocketAddress& addr) {
38     ASSERT(NULL == detect_);
39     ASSERT(NULL == socket_);
40     remote_ = addr;
41     if (remote_.IsAnyIP() && remote_.hostname().empty()) {
42       LOG_F(LS_ERROR) << "Empty address";
43       return SOCKET_ERROR;
44     }
45     Url<char> url("/", remote_.HostAsURIString(), remote_.port());
46     detect_ = new AutoDetectProxy(factory_->agent_);
47     detect_->set_server_url(url.url());
48     detect_->SignalWorkDone.connect(this,
49         &ProxySocketAdapter::OnProxyDetectionComplete);
50     detect_->Start();
51     return SOCKET_ERROR;
52   }
GetError() const53   virtual int GetError() const {
54     if (socket_) {
55       return socket_->GetError();
56     }
57     return detect_ ? EWOULDBLOCK : EADDRNOTAVAIL;
58   }
Close()59   virtual int Close() {
60     if (socket_) {
61       return socket_->Close();
62     }
63     if (detect_) {
64       detect_->Destroy(false);
65       detect_ = NULL;
66     }
67     return 0;
68   }
GetState() const69   virtual ConnState GetState() const {
70     if (socket_) {
71       return socket_->GetState();
72     }
73     return detect_ ? CS_CONNECTING : CS_CLOSED;
74   }
75 
76 private:
77   // AutoDetectProxy Slots
OnProxyDetectionComplete(SignalThread * thread)78   void OnProxyDetectionComplete(SignalThread* thread) {
79     ASSERT(detect_ == thread);
80     Attach(factory_->CreateProxySocket(detect_->proxy(), family_, type_));
81     detect_->Release();
82     detect_ = NULL;
83     if (0 == AsyncSocketAdapter::Connect(remote_)) {
84       SignalConnectEvent(this);
85     } else if (!IsBlockingError(socket_->GetError())) {
86       SignalCloseEvent(this, socket_->GetError());
87     }
88   }
89 
90   SslSocketFactory* factory_;
91   int family_;
92   int type_;
93   SocketAddress remote_;
94   AutoDetectProxy* detect_;
95 };
96 
97 ///////////////////////////////////////////////////////////////////////////////
98 // SslSocketFactory
99 ///////////////////////////////////////////////////////////////////////////////
100 
CreateSocket(int type)101 Socket* SslSocketFactory::CreateSocket(int type) {
102   return CreateSocket(AF_INET, type);
103 }
104 
CreateSocket(int family,int type)105 Socket* SslSocketFactory::CreateSocket(int family, int type) {
106   return factory_->CreateSocket(family, type);
107 }
108 
CreateAsyncSocket(int type)109 AsyncSocket* SslSocketFactory::CreateAsyncSocket(int type) {
110   return CreateAsyncSocket(AF_INET, type);
111 }
112 
CreateAsyncSocket(int family,int type)113 AsyncSocket* SslSocketFactory::CreateAsyncSocket(int family, int type) {
114   if (autodetect_proxy_) {
115     return new ProxySocketAdapter(this, family, type);
116   } else {
117     return CreateProxySocket(proxy_, family, type);
118   }
119 }
120 
121 
CreateProxySocket(const ProxyInfo & proxy,int family,int type)122 AsyncSocket* SslSocketFactory::CreateProxySocket(const ProxyInfo& proxy,
123                                                  int family,
124                                                  int type) {
125   AsyncSocket* socket = factory_->CreateAsyncSocket(family, type);
126   if (!socket)
127     return NULL;
128 
129   // Binary logging happens at the lowest level
130   if (!logging_label_.empty() && binary_mode_) {
131     socket = new LoggingSocketAdapter(socket, logging_level_,
132                                       logging_label_.c_str(), binary_mode_);
133   }
134 
135   if (proxy.type) {
136     AsyncSocket* proxy_socket = 0;
137     if (proxy_.type == PROXY_SOCKS5) {
138       proxy_socket = new AsyncSocksProxySocket(socket, proxy.address,
139                                                proxy.username, proxy.password);
140     } else {
141       // Note: we are trying unknown proxies as HTTPS currently
142       AsyncHttpsProxySocket* http_proxy =
143           new AsyncHttpsProxySocket(socket, agent_, proxy.address,
144                                     proxy.username, proxy.password);
145       http_proxy->SetForceConnect(force_connect_ || !hostname_.empty());
146       proxy_socket = http_proxy;
147     }
148     if (!proxy_socket) {
149       delete socket;
150       return NULL;
151     }
152     socket = proxy_socket;  // for our purposes the proxy is now the socket
153   }
154 
155   if (!hostname_.empty()) {
156     if (SSLAdapter* ssl_adapter = SSLAdapter::Create(socket)) {
157       ssl_adapter->set_ignore_bad_cert(ignore_bad_cert_);
158       ssl_adapter->StartSSL(hostname_.c_str(), true);
159       socket = ssl_adapter;
160     } else {
161       LOG_F(LS_ERROR) << "SSL unavailable";
162     }
163   }
164 
165   // Regular logging occurs at the highest level
166   if (!logging_label_.empty() && !binary_mode_) {
167     socket = new LoggingSocketAdapter(socket, logging_level_,
168                                       logging_label_.c_str(), binary_mode_);
169   }
170   return socket;
171 }
172 
173 ///////////////////////////////////////////////////////////////////////////////
174 
175 }  // namespace rtc
176