147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/* 247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Copyright 2007 The WebRTC Project Authors. All rights reserved. 347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * 447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Use of this source code is governed by a BSD-style license 547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * in the file PATENTS. All contributing project authors may 847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */ 1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/autodetectproxy.h" 1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/httpcommon.h" 1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/httpcommon-inl.h" 1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/socketadapters.h" 1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/ssladapter.h" 1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/sslsocketfactory.h" 1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc { 1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// ProxySocketAdapter 2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// TODO: Consider combining AutoDetectProxy and ProxySocketAdapter. I think 2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// the socket adapter is the more appropriate idiom for automatic proxy 2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// detection. We may or may not want to combine proxydetect.* as well. 2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass ProxySocketAdapter : public AsyncSocketAdapter { 2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ProxySocketAdapter(SslSocketFactory* factory, int family, int type) 3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org : AsyncSocketAdapter(NULL), factory_(factory), family_(family), 3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org type_(type), detect_(NULL) { 3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual ~ProxySocketAdapter() { 3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Close(); 3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual int Connect(const SocketAddress& addr) { 3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(NULL == detect_); 3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(NULL == socket_); 4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org remote_ = addr; 4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (remote_.IsAnyIP() && remote_.hostname().empty()) { 4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG_F(LS_ERROR) << "Empty address"; 4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SOCKET_ERROR; 4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Url<char> url("/", remote_.HostAsURIString(), remote_.port()); 4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org detect_ = new AutoDetectProxy(factory_->agent_); 4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org detect_->set_server_url(url.url()); 4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org detect_->SignalWorkDone.connect(this, 4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &ProxySocketAdapter::OnProxyDetectionComplete); 5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org detect_->Start(); 5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SOCKET_ERROR; 5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual int GetError() const { 5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (socket_) { 5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return socket_->GetError(); 5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return detect_ ? EWOULDBLOCK : EADDRNOTAVAIL; 5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual int Close() { 6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (socket_) { 6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return socket_->Close(); 6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (detect_) { 6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org detect_->Destroy(false); 6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org detect_ = NULL; 6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return 0; 6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual ConnState GetState() const { 7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (socket_) { 7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return socket_->GetState(); 7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return detect_ ? CS_CONNECTING : CS_CLOSED; 7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgprivate: 7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // AutoDetectProxy Slots 7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org void OnProxyDetectionComplete(SignalThread* thread) { 7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(detect_ == thread); 8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Attach(factory_->CreateProxySocket(detect_->proxy(), family_, type_)); 8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org detect_->Release(); 8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org detect_ = NULL; 8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (0 == AsyncSocketAdapter::Connect(remote_)) { 8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SignalConnectEvent(this); 8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (!IsBlockingError(socket_->GetError())) { 8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SignalCloseEvent(this, socket_->GetError()); 8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SslSocketFactory* factory_; 9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int family_; 9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int type_; 9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SocketAddress remote_; 9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AutoDetectProxy* detect_; 9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// SslSocketFactory 9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgSocket* SslSocketFactory::CreateSocket(int type) { 10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return CreateSocket(AF_INET, type); 10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgSocket* SslSocketFactory::CreateSocket(int family, int type) { 10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return factory_->CreateSocket(family, type); 10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgAsyncSocket* SslSocketFactory::CreateAsyncSocket(int type) { 11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return CreateAsyncSocket(AF_INET, type); 11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgAsyncSocket* SslSocketFactory::CreateAsyncSocket(int family, int type) { 11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (autodetect_proxy_) { 11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return new ProxySocketAdapter(this, family, type); 11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return CreateProxySocket(proxy_, family, type); 11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgAsyncSocket* SslSocketFactory::CreateProxySocket(const ProxyInfo& proxy, 12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int family, 12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int type) { 12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncSocket* socket = factory_->CreateAsyncSocket(family, type); 12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!socket) 12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return NULL; 12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Binary logging happens at the lowest level 13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!logging_label_.empty() && binary_mode_) { 13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket = new LoggingSocketAdapter(socket, logging_level_, 13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org logging_label_.c_str(), binary_mode_); 13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (proxy.type) { 13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncSocket* proxy_socket = 0; 13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (proxy_.type == PROXY_SOCKS5) { 13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy_socket = new AsyncSocksProxySocket(socket, proxy.address, 13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy.username, proxy.password); 14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Note: we are trying unknown proxies as HTTPS currently 14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncHttpsProxySocket* http_proxy = 14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org new AsyncHttpsProxySocket(socket, agent_, proxy.address, 14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy.username, proxy.password); 14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org http_proxy->SetForceConnect(force_connect_ || !hostname_.empty()); 14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy_socket = http_proxy; 14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!proxy_socket) { 14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete socket; 15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return NULL; 15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket = proxy_socket; // for our purposes the proxy is now the socket 15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!hostname_.empty()) { 15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (SSLAdapter* ssl_adapter = SSLAdapter::Create(socket)) { 15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ssl_adapter->set_ignore_bad_cert(ignore_bad_cert_); 15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ssl_adapter->StartSSL(hostname_.c_str(), true); 15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket = ssl_adapter; 16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG_F(LS_ERROR) << "SSL unavailable"; 16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Regular logging occurs at the highest level 16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!logging_label_.empty() && !binary_mode_) { 16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket = new LoggingSocketAdapter(socket, logging_level_, 16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org logging_label_.c_str(), binary_mode_); 16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return socket; 17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} // namespace rtc 176