From d415629de78b84bf539fda7f634996e159b0dcaa Mon Sep 17 00:00:00 2001 From: Peter Thatcher Date: Fri, 4 Sep 2015 04:21:07 -0700 Subject: [PATCH] Remove AsyncHttpRequest, AutoPortAllocator, ConnectivityChecker, and HttpPortAllocator. BUG=webrtc:4149, webrtc:4456 R=deadbeef@webrtc.org, pbos@webrtc.org Review URL: https://codereview.webrtc.org/1311353011 . Cr-Commit-Position: refs/heads/master@{#9857} --- webrtc/base/BUILD.gn | 2 - webrtc/base/asynchttprequest.cc | 118 +--- webrtc/base/asynchttprequest.h | 106 +--- webrtc/base/asynchttprequest_unittest.cc | 234 -------- webrtc/base/base.gyp | 2 - webrtc/base/base_tests.gyp | 1 - webrtc/p2p/client/connectivitychecker.cc | 529 ------------------ webrtc/p2p/client/connectivitychecker.h | 281 ---------- .../client/connectivitychecker_unittest.cc | 367 ------------ webrtc/p2p/client/httpportallocator.cc | 107 +--- webrtc/p2p/client/httpportallocator.h | 44 +- webrtc/p2p/client/portallocator_unittest.cc | 106 ---- webrtc/p2p/p2p.gyp | 3 - webrtc/p2p/p2p_tests.gypi | 1 - 14 files changed, 13 insertions(+), 1888 deletions(-) delete mode 100644 webrtc/base/asynchttprequest_unittest.cc delete mode 100644 webrtc/p2p/client/connectivitychecker.cc delete mode 100644 webrtc/p2p/client/connectivitychecker.h delete mode 100644 webrtc/p2p/client/connectivitychecker_unittest.cc diff --git a/webrtc/base/BUILD.gn b/webrtc/base/BUILD.gn index 475252c3ff..027fa45a01 100644 --- a/webrtc/base/BUILD.gn +++ b/webrtc/base/BUILD.gn @@ -197,8 +197,6 @@ static_library("rtc_base") { "arraysize.h", "asyncfile.cc", "asyncfile.h", - "asynchttprequest.cc", - "asynchttprequest.h", "asyncinvoker-inl.h", "asyncinvoker.cc", "asyncinvoker.h", diff --git a/webrtc/base/asynchttprequest.cc b/webrtc/base/asynchttprequest.cc index bdca585c31..310d82e040 100644 --- a/webrtc/base/asynchttprequest.cc +++ b/webrtc/base/asynchttprequest.cc @@ -1,116 +1,2 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/base/asynchttprequest.h" - -namespace rtc { - -enum { - MSG_TIMEOUT = SignalThread::ST_MSG_FIRST_AVAILABLE, - MSG_LAUNCH_REQUEST -}; -static const int kDefaultHTTPTimeout = 30 * 1000; // 30 sec - -/////////////////////////////////////////////////////////////////////////////// -// AsyncHttpRequest -/////////////////////////////////////////////////////////////////////////////// - -AsyncHttpRequest::AsyncHttpRequest(const std::string &user_agent) - : start_delay_(0), - firewall_(NULL), - port_(80), - secure_(false), - timeout_(kDefaultHTTPTimeout), - fail_redirect_(false), - factory_(Thread::Current()->socketserver(), user_agent), - pool_(&factory_), - client_(user_agent.c_str(), &pool_), - error_(HE_NONE) { - client_.SignalHttpClientComplete.connect(this, - &AsyncHttpRequest::OnComplete); -} - -AsyncHttpRequest::~AsyncHttpRequest() { -} - -void AsyncHttpRequest::OnWorkStart() { - if (start_delay_ <= 0) { - LaunchRequest(); - } else { - Thread::Current()->PostDelayed(start_delay_, this, MSG_LAUNCH_REQUEST); - } -} - -void AsyncHttpRequest::OnWorkStop() { - // worker is already quitting, no need to explicitly quit - LOG(LS_INFO) << "HttpRequest cancelled"; -} - -void AsyncHttpRequest::OnComplete(HttpClient* client, HttpErrorType error) { - Thread::Current()->Clear(this, MSG_TIMEOUT); - - set_error(error); - if (!error) { - LOG(LS_INFO) << "HttpRequest completed successfully"; - - std::string value; - if (client_.response().hasHeader(HH_LOCATION, &value)) { - response_redirect_ = value.c_str(); - } - } else { - LOG(LS_INFO) << "HttpRequest completed with error: " << error; - } - - worker()->Quit(); -} - -void AsyncHttpRequest::OnMessage(Message* message) { - switch (message->message_id) { - case MSG_TIMEOUT: - LOG(LS_INFO) << "HttpRequest timed out"; - client_.reset(); - worker()->Quit(); - break; - case MSG_LAUNCH_REQUEST: - LaunchRequest(); - break; - default: - SignalThread::OnMessage(message); - break; - } -} - -void AsyncHttpRequest::DoWork() { - // Do nothing while we wait for the request to finish. We only do this so - // that we can be a SignalThread; in the future this class should not be - // a SignalThread, since it does not need to spawn a new thread. - Thread::Current()->ProcessMessages(Thread::kForever); -} - -void AsyncHttpRequest::LaunchRequest() { - factory_.SetProxy(proxy_); - if (secure_) - factory_.UseSSL(host_.c_str()); - - bool transparent_proxy = (port_ == 80) && - ((proxy_.type == PROXY_HTTPS) || (proxy_.type == PROXY_UNKNOWN)); - if (transparent_proxy) { - client_.set_proxy(proxy_); - } - client_.set_fail_redirect(fail_redirect_); - client_.set_server(SocketAddress(host_, port_)); - - LOG(LS_INFO) << "HttpRequest start: " << host_ + client_.request().path; - - Thread::Current()->PostDelayed(timeout_, this, MSG_TIMEOUT); - client_.start(); -} - -} // namespace rtc +// TODO(pthatcher): Remove this file once chromium's GYP file doesn't +// refer to it. diff --git a/webrtc/base/asynchttprequest.h b/webrtc/base/asynchttprequest.h index b4bbf2539c..310d82e040 100644 --- a/webrtc/base/asynchttprequest.h +++ b/webrtc/base/asynchttprequest.h @@ -1,104 +1,2 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_ASYNCHTTPREQUEST_H_ -#define WEBRTC_BASE_ASYNCHTTPREQUEST_H_ - -#include -#include "webrtc/base/event.h" -#include "webrtc/base/httpclient.h" -#include "webrtc/base/signalthread.h" -#include "webrtc/base/socketpool.h" -#include "webrtc/base/sslsocketfactory.h" - -namespace rtc { - -class FirewallManager; - -/////////////////////////////////////////////////////////////////////////////// -// AsyncHttpRequest -// Performs an HTTP request on a background thread. Notifies on the foreground -// thread once the request is done (successfully or unsuccessfully). -/////////////////////////////////////////////////////////////////////////////// - -class AsyncHttpRequest : public SignalThread { - public: - explicit AsyncHttpRequest(const std::string &user_agent); - ~AsyncHttpRequest() override; - - // If start_delay is less than or equal to zero, this starts immediately. - // Start_delay defaults to zero. - int start_delay() const { return start_delay_; } - void set_start_delay(int delay) { start_delay_ = delay; } - - const ProxyInfo& proxy() const { return proxy_; } - void set_proxy(const ProxyInfo& proxy) { - proxy_ = proxy; - } - void set_firewall(FirewallManager * firewall) { - firewall_ = firewall; - } - - // The DNS name of the host to connect to. - const std::string& host() { return host_; } - void set_host(const std::string& host) { host_ = host; } - - // The port to connect to on the target host. - int port() { return port_; } - void set_port(int port) { port_ = port; } - - // Whether the request should use SSL. - bool secure() { return secure_; } - void set_secure(bool secure) { secure_ = secure; } - - // Time to wait on the download, in ms. - int timeout() { return timeout_; } - void set_timeout(int timeout) { timeout_ = timeout; } - - // Fail redirects to allow analysis of redirect urls, etc. - bool fail_redirect() const { return fail_redirect_; } - void set_fail_redirect(bool redirect) { fail_redirect_ = redirect; } - - // Returns the redirect when redirection occurs - const std::string& response_redirect() { return response_redirect_; } - - HttpRequestData& request() { return client_.request(); } - HttpResponseData& response() { return client_.response(); } - HttpErrorType error() { return error_; } - - protected: - void set_error(HttpErrorType error) { error_ = error; } - void OnWorkStart() override; - void OnWorkStop() override; - void OnComplete(HttpClient* client, HttpErrorType error); - void OnMessage(Message* message) override; - void DoWork() override; - - private: - void LaunchRequest(); - - int start_delay_; - ProxyInfo proxy_; - FirewallManager* firewall_; - std::string host_; - int port_; - bool secure_; - int timeout_; - bool fail_redirect_; - SslSocketFactory factory_; - ReuseSocketPool pool_; - HttpClient client_; - HttpErrorType error_; - std::string response_redirect_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_ASYNCHTTPREQUEST_H_ +// TODO(pthatcher): Remove this file once chromium's GYP file doesn't +// refer to it. diff --git a/webrtc/base/asynchttprequest_unittest.cc b/webrtc/base/asynchttprequest_unittest.cc deleted file mode 100644 index ddfad90143..0000000000 --- a/webrtc/base/asynchttprequest_unittest.cc +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "webrtc/base/asynchttprequest.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/httpserver.h" -#include "webrtc/base/socketstream.h" -#include "webrtc/base/thread.h" -#include "webrtc/test/testsupport/gtest_disable.h" - -namespace rtc { - -static const SocketAddress kServerAddr("127.0.0.1", 0); -static const SocketAddress kServerHostnameAddr("localhost", 0); -static const char kServerGetPath[] = "/get"; -static const char kServerPostPath[] = "/post"; -static const char kServerResponse[] = "This is a test"; - -class TestHttpServer : public HttpServer, public sigslot::has_slots<> { - public: - TestHttpServer(Thread* thread, const SocketAddress& addr) : - socket_(thread->socketserver()->CreateAsyncSocket(addr.family(), - SOCK_STREAM)) { - socket_->Bind(addr); - socket_->Listen(5); - socket_->SignalReadEvent.connect(this, &TestHttpServer::OnAccept); - } - - SocketAddress address() const { return socket_->GetLocalAddress(); } - void Close() const { socket_->Close(); } - - private: - void OnAccept(AsyncSocket* socket) { - AsyncSocket* new_socket = socket_->Accept(NULL); - if (new_socket) { - HandleConnection(new SocketStream(new_socket)); - } - } - rtc::scoped_ptr socket_; -}; - -class AsyncHttpRequestTest : public testing::Test, - public sigslot::has_slots<> { - public: - AsyncHttpRequestTest() - : started_(false), - done_(false), - server_(Thread::Current(), kServerAddr) { - server_.SignalHttpRequest.connect(this, &AsyncHttpRequestTest::OnRequest); - } - - bool started() const { return started_; } - bool done() const { return done_; } - - AsyncHttpRequest* CreateGetRequest(const std::string& host, int port, - const std::string& path) { - rtc::AsyncHttpRequest* request = - new rtc::AsyncHttpRequest("unittest"); - request->SignalWorkDone.connect(this, - &AsyncHttpRequestTest::OnRequestDone); - request->request().verb = rtc::HV_GET; - request->set_host(host); - request->set_port(port); - request->request().path = path; - request->response().document.reset(new MemoryStream()); - return request; - } - AsyncHttpRequest* CreatePostRequest(const std::string& host, int port, - const std::string& path, - const std::string content_type, - StreamInterface* content) { - rtc::AsyncHttpRequest* request = - new rtc::AsyncHttpRequest("unittest"); - request->SignalWorkDone.connect(this, - &AsyncHttpRequestTest::OnRequestDone); - request->request().verb = rtc::HV_POST; - request->set_host(host); - request->set_port(port); - request->request().path = path; - request->request().setContent(content_type, content); - request->response().document.reset(new MemoryStream()); - return request; - } - - const TestHttpServer& server() const { return server_; } - - protected: - void OnRequest(HttpServer* server, HttpServerTransaction* t) { - started_ = true; - - if (t->request.path == kServerGetPath) { - t->response.set_success("text/plain", new MemoryStream(kServerResponse)); - } else if (t->request.path == kServerPostPath) { - // reverse the data and reply - size_t size; - StreamInterface* in = t->request.document.get(); - StreamInterface* out = new MemoryStream(); - in->GetSize(&size); - for (size_t i = 0; i < size; ++i) { - char ch; - in->SetPosition(size - i - 1); - in->Read(&ch, 1, NULL, NULL); - out->Write(&ch, 1, NULL, NULL); - } - out->Rewind(); - t->response.set_success("text/plain", out); - } else { - t->response.set_error(404); - } - server_.Respond(t); - } - void OnRequestDone(SignalThread* thread) { - done_ = true; - } - - private: - bool started_; - bool done_; - TestHttpServer server_; -}; - -TEST_F(AsyncHttpRequestTest, TestGetSuccess) { - AsyncHttpRequest* req = CreateGetRequest( - kServerHostnameAddr.hostname(), server().address().port(), - kServerGetPath); - EXPECT_FALSE(started()); - req->Start(); - EXPECT_TRUE_WAIT(started(), 5000); // Should have started by now. - EXPECT_TRUE_WAIT(done(), 5000); - std::string response; - EXPECT_EQ(200U, req->response().scode); - ASSERT_TRUE(req->response().document); - req->response().document->Rewind(); - req->response().document->ReadLine(&response); - EXPECT_EQ(kServerResponse, response); - req->Release(); -} - -TEST_F(AsyncHttpRequestTest, TestGetNotFound) { - AsyncHttpRequest* req = CreateGetRequest( - kServerHostnameAddr.hostname(), server().address().port(), - "/bad"); - req->Start(); - EXPECT_TRUE_WAIT(done(), 5000); - size_t size; - EXPECT_EQ(404U, req->response().scode); - ASSERT_TRUE(req->response().document); - req->response().document->GetSize(&size); - EXPECT_EQ(0U, size); - req->Release(); -} - -TEST_F(AsyncHttpRequestTest, TestGetToNonServer) { - AsyncHttpRequest* req = CreateGetRequest( - "127.0.0.1", server().address().port(), - kServerGetPath); - // Stop the server before we send the request. - server().Close(); - req->Start(); - EXPECT_TRUE_WAIT(done(), 10000); - size_t size; - EXPECT_EQ(500U, req->response().scode); - ASSERT_TRUE(req->response().document); - req->response().document->GetSize(&size); - EXPECT_EQ(0U, size); - req->Release(); -} - -TEST_F(AsyncHttpRequestTest, DISABLED_TestGetToInvalidHostname) { - AsyncHttpRequest* req = CreateGetRequest( - "invalid", server().address().port(), - kServerGetPath); - req->Start(); - EXPECT_TRUE_WAIT(done(), 5000); - size_t size; - EXPECT_EQ(500U, req->response().scode); - ASSERT_TRUE(req->response().document); - req->response().document->GetSize(&size); - EXPECT_EQ(0U, size); - req->Release(); -} - -TEST_F(AsyncHttpRequestTest, TestPostSuccess) { - AsyncHttpRequest* req = CreatePostRequest( - kServerHostnameAddr.hostname(), server().address().port(), - kServerPostPath, "text/plain", new MemoryStream("abcd1234")); - req->Start(); - EXPECT_TRUE_WAIT(done(), 5000); - std::string response; - EXPECT_EQ(200U, req->response().scode); - ASSERT_TRUE(req->response().document); - req->response().document->Rewind(); - req->response().document->ReadLine(&response); - EXPECT_EQ("4321dcba", response); - req->Release(); -} - -// Ensure that we shut down properly even if work is outstanding. -TEST_F(AsyncHttpRequestTest, TestCancel) { - AsyncHttpRequest* req = CreateGetRequest( - kServerHostnameAddr.hostname(), server().address().port(), - kServerGetPath); - req->Start(); - req->Destroy(true); -} - -TEST_F(AsyncHttpRequestTest, TestGetSuccessDelay) { - AsyncHttpRequest* req = CreateGetRequest( - kServerHostnameAddr.hostname(), server().address().port(), - kServerGetPath); - req->set_start_delay(10); // Delay 10ms. - req->Start(); - Thread::SleepMs(5); - EXPECT_FALSE(started()); // Should not have started immediately. - EXPECT_TRUE_WAIT(started(), 5000); // Should have started by now. - EXPECT_TRUE_WAIT(done(), 5000); - std::string response; - EXPECT_EQ(200U, req->response().scode); - ASSERT_TRUE(req->response().document); - req->response().document->Rewind(); - req->response().document->ReadLine(&response); - EXPECT_EQ(kServerResponse, response); - req->Release(); -} - -} // namespace rtc diff --git a/webrtc/base/base.gyp b/webrtc/base/base.gyp index 37646a8637..6593729980 100644 --- a/webrtc/base/base.gyp +++ b/webrtc/base/base.gyp @@ -117,8 +117,6 @@ 'arraysize.h', 'asyncfile.cc', 'asyncfile.h', - 'asynchttprequest.cc', - 'asynchttprequest.h', 'asyncinvoker.cc', 'asyncinvoker.h', 'asyncinvoker-inl.h', diff --git a/webrtc/base/base_tests.gyp b/webrtc/base/base_tests.gyp index ec2ded07a3..4d7d74c506 100644 --- a/webrtc/base/base_tests.gyp +++ b/webrtc/base/base_tests.gyp @@ -44,7 +44,6 @@ 'type': 'none', 'direct_dependent_settings': { 'sources': [ - 'asynchttprequest_unittest.cc', 'atomicops_unittest.cc', 'autodetectproxy_unittest.cc', 'bandwidthsmoother_unittest.cc', diff --git a/webrtc/p2p/client/connectivitychecker.cc b/webrtc/p2p/client/connectivitychecker.cc deleted file mode 100644 index 8a7fc0d740..0000000000 --- a/webrtc/p2p/client/connectivitychecker.cc +++ /dev/null @@ -1,529 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/p2p/client/connectivitychecker.h" - -#include "webrtc/p2p/base/candidate.h" -#include "webrtc/p2p/base/common.h" -#include "webrtc/p2p/base/constants.h" -#include "webrtc/p2p/base/port.h" -#include "webrtc/p2p/base/relayport.h" -#include "webrtc/p2p/base/stunport.h" -#include "webrtc/base/asynchttprequest.h" -#include "webrtc/base/autodetectproxy.h" -#include "webrtc/base/helpers.h" -#include "webrtc/base/httpcommon-inl.h" -#include "webrtc/base/httpcommon.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/proxydetect.h" -#include "webrtc/base/thread.h" - -namespace cricket { - -static const char kDefaultStunHostname[] = "stun.l.google.com"; -static const int kDefaultStunPort = 19302; - -// Default maximum time in milliseconds we will wait for connections. -static const uint32 kDefaultTimeoutMs = 3000; - -enum { - MSG_START = 1, - MSG_STOP = 2, - MSG_TIMEOUT = 3, - MSG_SIGNAL_RESULTS = 4 -}; - -class TestHttpPortAllocator : public HttpPortAllocator { - public: - TestHttpPortAllocator(rtc::NetworkManager* network_manager, - const std::string& user_agent, - const std::string& relay_token) : - HttpPortAllocator(network_manager, user_agent) { - SetRelayToken(relay_token); - } - PortAllocatorSession* CreateSessionInternal( - const std::string& content_name, - int component, - const std::string& ice_ufrag, - const std::string& ice_pwd) { - return new TestHttpPortAllocatorSession(this, content_name, component, - ice_ufrag, ice_pwd, - stun_hosts(), relay_hosts(), - relay_token(), user_agent()); - } -}; - -void TestHttpPortAllocatorSession::ConfigReady(PortConfiguration* config) { - SignalConfigReady(username(), password(), config, proxy_); - delete config; -} - -void TestHttpPortAllocatorSession::OnRequestDone( - rtc::SignalThread* data) { - rtc::AsyncHttpRequest* request = - static_cast(data); - - // Tell the checker that the request is complete. - SignalRequestDone(request); - - // Pass on the response to super class. - HttpPortAllocatorSession::OnRequestDone(data); -} - -ConnectivityChecker::ConnectivityChecker( - rtc::Thread* worker, - const std::string& jid, - const std::string& session_id, - const std::string& user_agent, - const std::string& relay_token, - const std::string& connection) - : worker_(worker), - jid_(jid), - session_id_(session_id), - user_agent_(user_agent), - relay_token_(relay_token), - connection_(connection), - proxy_detect_(NULL), - timeout_ms_(kDefaultTimeoutMs), - stun_address_(kDefaultStunHostname, kDefaultStunPort), - started_(false) { -} - -ConnectivityChecker::~ConnectivityChecker() { - if (started_) { - // We try to clear the TIMEOUT below. But worker may still handle it and - // cause SignalCheckDone to happen on main-thread. So we finally clear any - // pending SIGNAL_RESULTS. - worker_->Clear(this, MSG_TIMEOUT); - worker_->Send(this, MSG_STOP); - nics_.clear(); - main_->Clear(this, MSG_SIGNAL_RESULTS); - } -} - -bool ConnectivityChecker::Initialize() { - network_manager_.reset(CreateNetworkManager()); - socket_factory_.reset(CreateSocketFactory(worker_)); - port_allocator_.reset(CreatePortAllocator(network_manager_.get(), - user_agent_, relay_token_)); - return true; -} - -void ConnectivityChecker::Start() { - main_ = rtc::Thread::Current(); - worker_->Post(this, MSG_START); - started_ = true; -} - -void ConnectivityChecker::CleanUp() { - ASSERT(worker_ == rtc::Thread::Current()); - if (proxy_detect_) { - proxy_detect_->Release(); - proxy_detect_ = NULL; - } - - for (uint32 i = 0; i < sessions_.size(); ++i) { - delete sessions_[i]; - } - sessions_.clear(); - for (uint32 i = 0; i < ports_.size(); ++i) { - delete ports_[i]; - } - ports_.clear(); -} - -bool ConnectivityChecker::AddNic(const rtc::IPAddress& ip, - const rtc::SocketAddress& proxy_addr) { - NicMap::iterator i = nics_.find(NicId(ip, proxy_addr)); - if (i != nics_.end()) { - // Already have it. - return false; - } - uint32 now = rtc::Time(); - NicInfo info; - info.ip = ip; - info.proxy_info = GetProxyInfo(); - info.stun.start_time_ms = now; - nics_.insert(std::pair(NicId(ip, proxy_addr), info)); - return true; -} - -void ConnectivityChecker::SetProxyInfo(const rtc::ProxyInfo& proxy_info) { - port_allocator_->set_proxy(user_agent_, proxy_info); - AllocatePorts(); -} - -rtc::ProxyInfo ConnectivityChecker::GetProxyInfo() const { - rtc::ProxyInfo proxy_info; - if (proxy_detect_) { - proxy_info = proxy_detect_->proxy(); - } - return proxy_info; -} - -void ConnectivityChecker::CheckNetworks() { - network_manager_->SignalNetworksChanged.connect( - this, &ConnectivityChecker::OnNetworksChanged); - network_manager_->StartUpdating(); -} - -void ConnectivityChecker::OnMessage(rtc::Message *msg) { - switch (msg->message_id) { - case MSG_START: - ASSERT(worker_ == rtc::Thread::Current()); - worker_->PostDelayed(timeout_ms_, this, MSG_TIMEOUT); - CheckNetworks(); - break; - case MSG_STOP: - // We're being stopped, free resources. - CleanUp(); - break; - case MSG_TIMEOUT: - // We need to signal results on the main thread. - main_->Post(this, MSG_SIGNAL_RESULTS); - break; - case MSG_SIGNAL_RESULTS: - ASSERT(main_ == rtc::Thread::Current()); - SignalCheckDone(this); - break; - default: - LOG(LS_ERROR) << "Unknown message: " << msg->message_id; - } -} - -void ConnectivityChecker::OnProxyDetect(rtc::SignalThread* thread) { - ASSERT(worker_ == rtc::Thread::Current()); - if (proxy_detect_->proxy().type != rtc::PROXY_NONE) { - SetProxyInfo(proxy_detect_->proxy()); - } -} - -void ConnectivityChecker::OnRequestDone(rtc::AsyncHttpRequest* request) { - ASSERT(worker_ == rtc::Thread::Current()); - // Since we don't know what nic were actually used for the http request, - // for now, just use the first one. - std::vector networks; - network_manager_->GetNetworks(&networks); - if (networks.empty()) { - LOG(LS_ERROR) << "No networks while registering http start."; - return; - } - rtc::ProxyInfo proxy_info = request->proxy(); - NicMap::iterator i = - nics_.find(NicId(networks[0]->GetBestIP(), proxy_info.address)); - if (i != nics_.end()) { - int port = request->port(); - uint32 now = rtc::Time(); - NicInfo* nic_info = &i->second; - if (port == rtc::HTTP_SECURE_PORT) { - nic_info->https.rtt = now - nic_info->https.start_time_ms; - } else { - LOG(LS_ERROR) << "Got response with unknown port: " << port; - } - } else { - LOG(LS_ERROR) << "No nic info found while receiving response."; - } -} - -void ConnectivityChecker::OnConfigReady( - const std::string& username, const std::string& password, - const PortConfiguration* config, const rtc::ProxyInfo& proxy_info) { - ASSERT(worker_ == rtc::Thread::Current()); - - // Since we send requests on both HTTP and HTTPS we will get two - // configs per nic. Results from the second will overwrite the - // result from the first. - // TODO: Handle multiple pings on one nic. - CreateRelayPorts(username, password, config, proxy_info); -} - -void ConnectivityChecker::OnRelayPortComplete(Port* port) { - ASSERT(worker_ == rtc::Thread::Current()); - RelayPort* relay_port = reinterpret_cast(port); - const ProtocolAddress* address = relay_port->ServerAddress(0); - rtc::IPAddress ip = port->Network()->GetBestIP(); - NicMap::iterator i = nics_.find(NicId(ip, port->proxy().address)); - if (i != nics_.end()) { - // We have it already, add the new information. - NicInfo* nic_info = &i->second; - ConnectInfo* connect_info = NULL; - if (address) { - switch (address->proto) { - case PROTO_UDP: - connect_info = &nic_info->udp; - break; - case PROTO_TCP: - connect_info = &nic_info->tcp; - break; - case PROTO_SSLTCP: - connect_info = &nic_info->ssltcp; - break; - default: - LOG(LS_ERROR) << " relay address with bad protocol added"; - } - if (connect_info) { - connect_info->rtt = - rtc::TimeSince(connect_info->start_time_ms); - } - } - } else { - LOG(LS_ERROR) << " got relay address for non-existing nic"; - } -} - -void ConnectivityChecker::OnStunPortComplete(Port* port) { - ASSERT(worker_ == rtc::Thread::Current()); - const std::vector candidates = port->Candidates(); - Candidate c = candidates[0]; - rtc::IPAddress ip = port->Network()->GetBestIP(); - NicMap::iterator i = nics_.find(NicId(ip, port->proxy().address)); - if (i != nics_.end()) { - // We have it already, add the new information. - uint32 now = rtc::Time(); - NicInfo* nic_info = &i->second; - nic_info->external_address = c.address(); - - nic_info->stun_server_addresses = - static_cast(port)->server_addresses(); - nic_info->stun.rtt = now - nic_info->stun.start_time_ms; - } else { - LOG(LS_ERROR) << "Got stun address for non-existing nic"; - } -} - -void ConnectivityChecker::OnStunPortError(Port* port) { - ASSERT(worker_ == rtc::Thread::Current()); - LOG(LS_ERROR) << "Stun address error."; - rtc::IPAddress ip = port->Network()->GetBestIP(); - NicMap::iterator i = nics_.find(NicId(ip, port->proxy().address)); - if (i != nics_.end()) { - // We have it already, add the new information. - NicInfo* nic_info = &i->second; - - nic_info->stun_server_addresses = - static_cast(port)->server_addresses(); - } -} - -void ConnectivityChecker::OnRelayPortError(Port* port) { - ASSERT(worker_ == rtc::Thread::Current()); - LOG(LS_ERROR) << "Relay address error."; -} - -void ConnectivityChecker::OnNetworksChanged() { - ASSERT(worker_ == rtc::Thread::Current()); - std::vector networks; - network_manager_->GetNetworks(&networks); - if (networks.empty()) { - LOG(LS_ERROR) << "Machine has no networks; nothing to do"; - return; - } - AllocatePorts(); -} - -HttpPortAllocator* ConnectivityChecker::CreatePortAllocator( - rtc::NetworkManager* network_manager, - const std::string& user_agent, - const std::string& relay_token) { - return new TestHttpPortAllocator(network_manager, user_agent, relay_token); -} - -StunPort* ConnectivityChecker::CreateStunPort( - const std::string& username, const std::string& password, - const PortConfiguration* config, rtc::Network* network) { - return StunPort::Create(worker_, - socket_factory_.get(), - network, - network->GetBestIP(), - 0, - 0, - username, - password, - config->stun_servers, - std::string()); -} - -RelayPort* ConnectivityChecker::CreateRelayPort( - const std::string& username, const std::string& password, - const PortConfiguration* config, rtc::Network* network) { - return RelayPort::Create(worker_, - socket_factory_.get(), - network, - network->GetBestIP(), - port_allocator_->min_port(), - port_allocator_->max_port(), - username, - password); -} - -void ConnectivityChecker::CreateRelayPorts( - const std::string& username, const std::string& password, - const PortConfiguration* config, const rtc::ProxyInfo& proxy_info) { - PortConfiguration::RelayList::const_iterator relay; - std::vector networks; - network_manager_->GetNetworks(&networks); - if (networks.empty()) { - LOG(LS_ERROR) << "Machine has no networks; no relay ports created."; - return; - } - for (relay = config->relays.begin(); - relay != config->relays.end(); ++relay) { - for (uint32 i = 0; i < networks.size(); ++i) { - NicMap::iterator iter = - nics_.find(NicId(networks[i]->GetBestIP(), proxy_info.address)); - if (iter != nics_.end()) { - // TODO: Now setting the same start time for all protocols. - // This might affect accuracy, but since we are mainly looking for - // connect failures or number that stick out, this is good enough. - uint32 now = rtc::Time(); - NicInfo* nic_info = &iter->second; - nic_info->udp.start_time_ms = now; - nic_info->tcp.start_time_ms = now; - nic_info->ssltcp.start_time_ms = now; - - // Add the addresses of this protocol. - PortList::const_iterator relay_port; - for (relay_port = relay->ports.begin(); - relay_port != relay->ports.end(); - ++relay_port) { - RelayPort* port = CreateRelayPort(username, password, - config, networks[i]); - port->AddServerAddress(*relay_port); - port->AddExternalAddress(*relay_port); - - nic_info->media_server_address = port->ServerAddress(0)->address; - - // Listen to network events. - port->SignalPortComplete.connect( - this, &ConnectivityChecker::OnRelayPortComplete); - port->SignalPortError.connect( - this, &ConnectivityChecker::OnRelayPortError); - - port->set_proxy(user_agent_, proxy_info); - - // Start fetching an address for this port. - port->PrepareAddress(); - ports_.push_back(port); - } - } else { - LOG(LS_ERROR) << "Failed to find nic info when creating relay ports."; - } - } - } -} - -void ConnectivityChecker::AllocatePorts() { - const std::string username = rtc::CreateRandomString(ICE_UFRAG_LENGTH); - const std::string password = rtc::CreateRandomString(ICE_PWD_LENGTH); - ServerAddresses stun_servers; - stun_servers.insert(stun_address_); - PortConfiguration config(stun_servers, username, password); - std::vector networks; - network_manager_->GetNetworks(&networks); - if (networks.empty()) { - LOG(LS_ERROR) << "Machine has no networks; no ports will be allocated"; - return; - } - rtc::ProxyInfo proxy_info = GetProxyInfo(); - bool allocate_relay_ports = false; - for (uint32 i = 0; i < networks.size(); ++i) { - if (AddNic(networks[i]->GetBestIP(), proxy_info.address)) { - Port* port = CreateStunPort(username, password, &config, networks[i]); - if (port) { - - // Listen to network events. - port->SignalPortComplete.connect( - this, &ConnectivityChecker::OnStunPortComplete); - port->SignalPortError.connect( - this, &ConnectivityChecker::OnStunPortError); - - port->set_proxy(user_agent_, proxy_info); - port->PrepareAddress(); - ports_.push_back(port); - allocate_relay_ports = true; - } - } - } - - // If any new ip/proxy combinations were added, send a relay allocate. - if (allocate_relay_ports) { - AllocateRelayPorts(); - } - - // Initiate proxy detection. - InitiateProxyDetection(); -} - -void ConnectivityChecker::InitiateProxyDetection() { - // Only start if we haven't been started before. - if (!proxy_detect_) { - proxy_detect_ = new rtc::AutoDetectProxy(user_agent_); - rtc::Url host_url("/", "relay.google.com", - rtc::HTTP_SECURE_PORT); - host_url.set_secure(true); - proxy_detect_->set_server_url(host_url.url()); - proxy_detect_->SignalWorkDone.connect( - this, &ConnectivityChecker::OnProxyDetect); - proxy_detect_->Start(); - } -} - -void ConnectivityChecker::AllocateRelayPorts() { - // Currently we are using the 'default' nic for http(s) requests. - TestHttpPortAllocatorSession* allocator_session = - reinterpret_cast( - port_allocator_->CreateSessionInternal( - "connectivity checker test content", - ICE_CANDIDATE_COMPONENT_RTP, - rtc::CreateRandomString(ICE_UFRAG_LENGTH), - rtc::CreateRandomString(ICE_PWD_LENGTH))); - allocator_session->set_proxy(port_allocator_->proxy()); - allocator_session->SignalConfigReady.connect( - this, &ConnectivityChecker::OnConfigReady); - allocator_session->SignalRequestDone.connect( - this, &ConnectivityChecker::OnRequestDone); - - // Try https only since using http would result in credentials being sent - // over the network unprotected. - RegisterHttpStart(rtc::HTTP_SECURE_PORT); - allocator_session->SendSessionRequest("relay.l.google.com", - rtc::HTTP_SECURE_PORT); - - sessions_.push_back(allocator_session); -} - -void ConnectivityChecker::RegisterHttpStart(int port) { - // Since we don't know what nic were actually used for the http request, - // for now, just use the first one. - std::vector networks; - network_manager_->GetNetworks(&networks); - if (networks.empty()) { - LOG(LS_ERROR) << "No networks while registering http start."; - return; - } - rtc::ProxyInfo proxy_info = GetProxyInfo(); - NicMap::iterator i = - nics_.find(NicId(networks[0]->GetBestIP(), proxy_info.address)); - if (i != nics_.end()) { - uint32 now = rtc::Time(); - NicInfo* nic_info = &i->second; - if (port == rtc::HTTP_SECURE_PORT) { - nic_info->https.start_time_ms = now; - } else { - LOG(LS_ERROR) << "Registering start time for unknown port: " << port; - } - } else { - LOG(LS_ERROR) << "Error, no nic info found while registering http start."; - } -} - -} // namespace rtc diff --git a/webrtc/p2p/client/connectivitychecker.h b/webrtc/p2p/client/connectivitychecker.h deleted file mode 100644 index 427749e5b5..0000000000 --- a/webrtc/p2p/client/connectivitychecker.h +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_P2P_CLIENT_CONNECTIVITYCHECKER_H_ -#define WEBRTC_P2P_CLIENT_CONNECTIVITYCHECKER_H_ - -#include -#include - -#include "webrtc/p2p/base/basicpacketsocketfactory.h" -#include "webrtc/p2p/client/httpportallocator.h" -#include "webrtc/base/basictypes.h" -#include "webrtc/base/messagehandler.h" -#include "webrtc/base/network.h" -#include "webrtc/base/proxyinfo.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/sigslot.h" -#include "webrtc/base/socketaddress.h" - -namespace rtc { -class AsyncHttpRequest; -class AutoDetectProxy; -class BasicPacketSocketFactory; -class NetworkManager; -class PacketSocketFactory; -class SignalThread; -class TestHttpPortAllocatorSession; -class Thread; -} - -namespace cricket { -class HttpPortAllocator; -class Port; -class PortAllocatorSession; -struct PortConfiguration; -class RelayPort; -class StunPort; - -// Contains details about a discovered firewall that are of interest -// when debugging call failures. -struct FirewallInfo { - std::string brand; - std::string model; - - // TODO: List of current port mappings. -}; - -// Contains details about a specific connect attempt. -struct ConnectInfo { - ConnectInfo() - : rtt(-1), error(0) {} - // Time when the connection was initiated. Needed for calculating - // the round trip time. - uint32 start_time_ms; - // Round trip time in milliseconds or -1 for failed connection. - int32 rtt; - // Error code representing low level errors like socket errors. - int error; -}; - -// Identifier for a network interface and proxy address pair. -struct NicId { - NicId(const rtc::IPAddress& ip, - const rtc::SocketAddress& proxy_address) - : ip(ip), - proxy_address(proxy_address) { - } - rtc::IPAddress ip; - rtc::SocketAddress proxy_address; -}; - -// Comparator implementation identifying unique network interface and -// proxy address pairs. -class NicIdComparator { - public: - int compare(const NicId &first, const NicId &second) const { - if (first.ip == second.ip) { - // Compare proxy address. - if (first.proxy_address == second.proxy_address) { - return 0; - } else { - return first.proxy_address < second.proxy_address? -1 : 1; - } - } - return first.ip < second.ip ? -1 : 1; - } - - bool operator()(const NicId &first, const NicId &second) const { - return (compare(first, second) < 0); - } -}; - -// Contains information of a network interface and proxy address pair. -struct NicInfo { - NicInfo() {} - rtc::IPAddress ip; - rtc::ProxyInfo proxy_info; - rtc::SocketAddress external_address; - ServerAddresses stun_server_addresses; - rtc::SocketAddress media_server_address; - ConnectInfo stun; - ConnectInfo http; - ConnectInfo https; - ConnectInfo udp; - ConnectInfo tcp; - ConnectInfo ssltcp; - FirewallInfo firewall; -}; - -// Holds the result of the connectivity check. -class NicMap : public std::map { -}; - -class TestHttpPortAllocatorSession : public HttpPortAllocatorSession { - public: - TestHttpPortAllocatorSession( - HttpPortAllocator* allocator, - const std::string& content_name, - int component, - const std::string& ice_ufrag, - const std::string& ice_pwd, - const std::vector& stun_hosts, - const std::vector& relay_hosts, - const std::string& relay_token, - const std::string& user_agent) - : HttpPortAllocatorSession( - allocator, content_name, component, ice_ufrag, ice_pwd, stun_hosts, - relay_hosts, relay_token, user_agent) { - } - void set_proxy(const rtc::ProxyInfo& proxy) { - proxy_ = proxy; - } - - void ConfigReady(PortConfiguration* config); - - void OnRequestDone(rtc::SignalThread* data); - - sigslot::signal4 SignalConfigReady; - sigslot::signal1 SignalRequestDone; - - private: - rtc::ProxyInfo proxy_; -}; - -// Runs a request/response check on all network interface and proxy -// address combinations. The check is considered done either when all -// checks has been successful or when the check times out. -class ConnectivityChecker - : public rtc::MessageHandler, public sigslot::has_slots<> { - public: - ConnectivityChecker(rtc::Thread* worker, - const std::string& jid, - const std::string& session_id, - const std::string& user_agent, - const std::string& relay_token, - const std::string& connection); - virtual ~ConnectivityChecker(); - - // Virtual for gMock. - virtual bool Initialize(); - virtual void Start(); - - // MessageHandler implementation. - virtual void OnMessage(rtc::Message *msg); - - // Instruct checker to stop and wait until that's done. - // Virtual for gMock. - virtual void Stop() { - worker_->Stop(); - } - - const NicMap& GetResults() const { - return nics_; - } - - void set_timeout_ms(uint32 timeout) { - timeout_ms_ = timeout; - } - - void set_stun_address(const rtc::SocketAddress& stun_address) { - stun_address_ = stun_address; - } - - const std::string& connection() const { - return connection_; - } - - const std::string& jid() const { - return jid_; - } - - const std::string& session_id() const { - return session_id_; - } - - // Context: Main Thread. Signalled when the connectivity check is complete. - sigslot::signal1 SignalCheckDone; - - protected: - // Can be overridden for test. - virtual rtc::NetworkManager* CreateNetworkManager() { - return new rtc::BasicNetworkManager(); - } - virtual rtc::BasicPacketSocketFactory* CreateSocketFactory( - rtc::Thread* thread) { - return new rtc::BasicPacketSocketFactory(thread); - } - virtual HttpPortAllocator* CreatePortAllocator( - rtc::NetworkManager* network_manager, - const std::string& user_agent, - const std::string& relay_token); - virtual StunPort* CreateStunPort( - const std::string& username, const std::string& password, - const PortConfiguration* config, rtc::Network* network); - virtual RelayPort* CreateRelayPort( - const std::string& username, const std::string& password, - const PortConfiguration* config, rtc::Network* network); - virtual void InitiateProxyDetection(); - virtual void SetProxyInfo(const rtc::ProxyInfo& info); - virtual rtc::ProxyInfo GetProxyInfo() const; - - rtc::Thread* worker() { - return worker_; - } - - private: - bool AddNic(const rtc::IPAddress& ip, - const rtc::SocketAddress& proxy_address); - void AllocatePorts(); - void AllocateRelayPorts(); - void CheckNetworks(); - void CreateRelayPorts( - const std::string& username, const std::string& password, - const PortConfiguration* config, const rtc::ProxyInfo& proxy_info); - - // Must be called by the worker thread. - void CleanUp(); - - void OnRequestDone(rtc::AsyncHttpRequest* request); - void OnRelayPortComplete(Port* port); - void OnStunPortComplete(Port* port); - void OnRelayPortError(Port* port); - void OnStunPortError(Port* port); - void OnNetworksChanged(); - void OnProxyDetect(rtc::SignalThread* thread); - void OnConfigReady( - const std::string& username, const std::string& password, - const PortConfiguration* config, const rtc::ProxyInfo& proxy); - void OnConfigWithProxyReady(const PortConfiguration*); - void RegisterHttpStart(int port); - rtc::Thread* worker_; - std::string jid_; - std::string session_id_; - std::string user_agent_; - std::string relay_token_; - std::string connection_; - rtc::AutoDetectProxy* proxy_detect_; - rtc::scoped_ptr network_manager_; - rtc::scoped_ptr socket_factory_; - rtc::scoped_ptr port_allocator_; - NicMap nics_; - std::vector ports_; - std::vector sessions_; - uint32 timeout_ms_; - rtc::SocketAddress stun_address_; - rtc::Thread* main_; - bool started_; -}; - -} // namespace cricket - -#endif // WEBRTC_P2P_CLIENT_CONNECTIVITYCHECKER_H_ diff --git a/webrtc/p2p/client/connectivitychecker_unittest.cc b/webrtc/p2p/client/connectivitychecker_unittest.cc deleted file mode 100644 index d590a7206f..0000000000 --- a/webrtc/p2p/client/connectivitychecker_unittest.cc +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright 2011 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/p2p/base/basicpacketsocketfactory.h" -#include "webrtc/p2p/base/relayport.h" -#include "webrtc/p2p/base/stunport.h" -#include "webrtc/p2p/client/connectivitychecker.h" -#include "webrtc/p2p/client/httpportallocator.h" -#include "webrtc/base/asynchttprequest.h" -#include "webrtc/base/fakenetwork.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/socketaddress.h" - -namespace cricket { - -static const rtc::SocketAddress kClientAddr1("11.11.11.11", 0); -static const rtc::SocketAddress kClientAddr2("22.22.22.22", 0); -static const rtc::SocketAddress kExternalAddr("33.33.33.33", 3333); -static const rtc::SocketAddress kStunAddr("44.44.44.44", 4444); -static const rtc::SocketAddress kRelayAddr("55.55.55.55", 5555); -static const rtc::SocketAddress kProxyAddr("66.66.66.66", 6666); -static const rtc::ProxyType kProxyType = rtc::PROXY_HTTPS; -static const char kRelayHost[] = "relay.google.com"; -static const char kRelayToken[] = - "CAESFwoOb2phQGdvb2dsZS5jb20Q043h47MmGhBTB1rbfIXkhuarDCZe+xF6"; -static const char kBrowserAgent[] = "browser_test"; -static const char kJid[] = "a.b@c"; -static const char kUserName[] = "testuser"; -static const char kPassword[] = "testpassword"; -static const char kMagicCookie[] = "testcookie"; -static const char kRelayUdpPort[] = "4444"; -static const char kRelayTcpPort[] = "5555"; -static const char kRelaySsltcpPort[] = "6666"; -static const char kSessionId[] = "testsession"; -static const char kConnection[] = "testconnection"; -static const int kMinPort = 1000; -static const int kMaxPort = 2000; - -// Fake implementation to mock away real network usage. -class FakeRelayPort : public RelayPort { - public: - FakeRelayPort(rtc::Thread* thread, - rtc::PacketSocketFactory* factory, - rtc::Network* network, const rtc::IPAddress& ip, - int min_port, int max_port, - const std::string& username, const std::string& password) - : RelayPort(thread, factory, network, ip, min_port, max_port, - username, password) { - } - - // Just signal that we are done. - virtual void PrepareAddress() { - SignalPortComplete(this); - } -}; - -// Fake implementation to mock away real network usage. -class FakeStunPort : public StunPort { - public: - FakeStunPort(rtc::Thread* thread, - rtc::PacketSocketFactory* factory, - rtc::Network* network, - const rtc::IPAddress& ip, - int min_port, int max_port, - const std::string& username, const std::string& password, - const ServerAddresses& server_addr) - : StunPort(thread, factory, network, ip, min_port, max_port, - username, password, server_addr, std::string()) { - } - - // Just set external address and signal that we are done. - virtual void PrepareAddress() { - AddAddress(kExternalAddr, kExternalAddr, rtc::SocketAddress(), "udp", "", - "", STUN_PORT_TYPE, ICE_TYPE_PREFERENCE_SRFLX, 0, true); - SignalPortComplete(this); - } -}; - -// Fake implementation to mock away real network usage by responding -// to http requests immediately. -class FakeHttpPortAllocatorSession : public TestHttpPortAllocatorSession { - public: - FakeHttpPortAllocatorSession( - HttpPortAllocator* allocator, - const std::string& content_name, - int component, - const std::string& ice_ufrag, const std::string& ice_pwd, - const std::vector& stun_hosts, - const std::vector& relay_hosts, - const std::string& relay_token, - const std::string& agent) - : TestHttpPortAllocatorSession(allocator, - content_name, - component, - ice_ufrag, - ice_pwd, - stun_hosts, - relay_hosts, - relay_token, - agent) { - } - virtual void SendSessionRequest(const std::string& host, int port) { - FakeReceiveSessionResponse(host, port); - } - - // Pass results to the real implementation. - void FakeReceiveSessionResponse(const std::string& host, int port) { - rtc::AsyncHttpRequest* response = CreateAsyncHttpResponse(port); - TestHttpPortAllocatorSession::OnRequestDone(response); - response->Destroy(true); - } - - private: - // Helper method for creating a response to a relay session request. - rtc::AsyncHttpRequest* CreateAsyncHttpResponse(int port) { - rtc::AsyncHttpRequest* request = - new rtc::AsyncHttpRequest(kBrowserAgent); - std::stringstream ss; - ss << "username=" << kUserName << std::endl - << "password=" << kPassword << std::endl - << "magic_cookie=" << kMagicCookie << std::endl - << "relay.ip=" << kRelayAddr.ipaddr().ToString() << std::endl - << "relay.udp_port=" << kRelayUdpPort << std::endl - << "relay.tcp_port=" << kRelayTcpPort << std::endl - << "relay.ssltcp_port=" << kRelaySsltcpPort << std::endl; - request->response().document.reset( - new rtc::MemoryStream(ss.str().c_str())); - request->response().set_success(); - request->set_port(port); - request->set_secure(port == rtc::HTTP_SECURE_PORT); - return request; - } -}; - -// Fake implementation for creating fake http sessions. -class FakeHttpPortAllocator : public HttpPortAllocator { - public: - FakeHttpPortAllocator(rtc::NetworkManager* network_manager, - const std::string& user_agent) - : HttpPortAllocator(network_manager, user_agent) { - } - - virtual PortAllocatorSession* CreateSessionInternal( - const std::string& content_name, int component, - const std::string& ice_ufrag, const std::string& ice_pwd) { - std::vector stun_hosts; - stun_hosts.push_back(kStunAddr); - std::vector relay_hosts; - relay_hosts.push_back(kRelayHost); - return new FakeHttpPortAllocatorSession(this, - content_name, - component, - ice_ufrag, - ice_pwd, - stun_hosts, - relay_hosts, - kRelayToken, - kBrowserAgent); - } -}; - -class ConnectivityCheckerForTest : public ConnectivityChecker { - public: - ConnectivityCheckerForTest(rtc::Thread* worker, - const std::string& jid, - const std::string& session_id, - const std::string& user_agent, - const std::string& relay_token, - const std::string& connection) - : ConnectivityChecker(worker, - jid, - session_id, - user_agent, - relay_token, - connection), - proxy_initiated_(false) { - } - - rtc::FakeNetworkManager* network_manager() const { - return network_manager_; - } - - FakeHttpPortAllocator* port_allocator() const { - return fake_port_allocator_; - } - - protected: - // Overridden methods for faking a real network. - virtual rtc::NetworkManager* CreateNetworkManager() { - network_manager_ = new rtc::FakeNetworkManager(); - return network_manager_; - } - virtual rtc::BasicPacketSocketFactory* CreateSocketFactory( - rtc::Thread* thread) { - // Create socket factory, for simplicity, let it run on the current thread. - socket_factory_ = - new rtc::BasicPacketSocketFactory(rtc::Thread::Current()); - return socket_factory_; - } - virtual HttpPortAllocator* CreatePortAllocator( - rtc::NetworkManager* network_manager, - const std::string& user_agent, - const std::string& relay_token) { - fake_port_allocator_ = - new FakeHttpPortAllocator(network_manager, user_agent); - return fake_port_allocator_; - } - virtual StunPort* CreateStunPort( - const std::string& username, const std::string& password, - const PortConfiguration* config, rtc::Network* network) { - return new FakeStunPort(worker(), - socket_factory_, - network, - network->GetBestIP(), - kMinPort, - kMaxPort, - username, - password, - config->stun_servers); - } - virtual RelayPort* CreateRelayPort( - const std::string& username, const std::string& password, - const PortConfiguration* config, rtc::Network* network) { - return new FakeRelayPort(worker(), - socket_factory_, - network, - network->GetBestIP(), - kMinPort, - kMaxPort, - username, - password); - } - virtual void InitiateProxyDetection() { - if (!proxy_initiated_) { - proxy_initiated_ = true; - proxy_info_.address = kProxyAddr; - proxy_info_.type = kProxyType; - SetProxyInfo(proxy_info_); - } - } - - virtual rtc::ProxyInfo GetProxyInfo() const { - return proxy_info_; - } - - private: - rtc::BasicPacketSocketFactory* socket_factory_; - FakeHttpPortAllocator* fake_port_allocator_; - rtc::FakeNetworkManager* network_manager_; - rtc::ProxyInfo proxy_info_; - bool proxy_initiated_; -}; - -class ConnectivityCheckerTest : public testing::Test { - protected: - void VerifyNic(const NicInfo& info, - const rtc::SocketAddress& local_address) { - // Verify that the external address has been set. - EXPECT_EQ(kExternalAddr, info.external_address); - - // Verify that the stun server address has been set. - EXPECT_EQ(1U, info.stun_server_addresses.size()); - EXPECT_EQ(kStunAddr, *(info.stun_server_addresses.begin())); - - // Verify that the media server address has been set. Don't care - // about port since it is different for different protocols. - EXPECT_EQ(kRelayAddr.ipaddr(), info.media_server_address.ipaddr()); - - // Verify that local ip matches. - EXPECT_EQ(local_address.ipaddr(), info.ip); - - // Verify that we have received responses for our - // pings. Unsuccessful ping has rtt value -1, successful >= 0. - EXPECT_GE(info.stun.rtt, 0); - EXPECT_GE(info.udp.rtt, 0); - EXPECT_GE(info.tcp.rtt, 0); - EXPECT_GE(info.ssltcp.rtt, 0); - - // If proxy has been set, verify address and type. - if (!info.proxy_info.address.IsNil()) { - EXPECT_EQ(kProxyAddr, info.proxy_info.address); - EXPECT_EQ(kProxyType, info.proxy_info.type); - } - } -}; - -// Tests a configuration with two network interfaces. Verifies that 4 -// combinations of ip/proxy are created and that all protocols are -// tested on each combination. -TEST_F(ConnectivityCheckerTest, TestStart) { - ConnectivityCheckerForTest connectivity_checker(rtc::Thread::Current(), - kJid, - kSessionId, - kBrowserAgent, - kRelayToken, - kConnection); - connectivity_checker.Initialize(); - connectivity_checker.set_stun_address(kStunAddr); - connectivity_checker.network_manager()->AddInterface(kClientAddr1); - connectivity_checker.network_manager()->AddInterface(kClientAddr2); - - connectivity_checker.Start(); - rtc::Thread::Current()->ProcessMessages(1000); - - NicMap nics = connectivity_checker.GetResults(); - - // There should be 4 nics in our map. 2 for each interface added, - // one with proxy set and one without. - EXPECT_EQ(4U, nics.size()); - - // First verify interfaces without proxy. - rtc::SocketAddress nilAddress; - - // First lookup the address of the first nic combined with no proxy. - NicMap::iterator i = nics.find(NicId(kClientAddr1.ipaddr(), nilAddress)); - ASSERT(i != nics.end()); - NicInfo info = i->second; - VerifyNic(info, kClientAddr1); - - // Then make sure the second device has been tested without proxy. - i = nics.find(NicId(kClientAddr2.ipaddr(), nilAddress)); - ASSERT(i != nics.end()); - info = i->second; - VerifyNic(info, kClientAddr2); - - // Now verify both interfaces with proxy. - i = nics.find(NicId(kClientAddr1.ipaddr(), kProxyAddr)); - ASSERT(i != nics.end()); - info = i->second; - VerifyNic(info, kClientAddr1); - - i = nics.find(NicId(kClientAddr2.ipaddr(), kProxyAddr)); - ASSERT(i != nics.end()); - info = i->second; - VerifyNic(info, kClientAddr2); -}; - -// Tests that nothing bad happens if thera are no network interfaces -// available to check. -TEST_F(ConnectivityCheckerTest, TestStartNoNetwork) { - ConnectivityCheckerForTest connectivity_checker(rtc::Thread::Current(), - kJid, - kSessionId, - kBrowserAgent, - kRelayToken, - kConnection); - connectivity_checker.Initialize(); - connectivity_checker.Start(); - rtc::Thread::Current()->ProcessMessages(1000); - - NicMap nics = connectivity_checker.GetResults(); - - // Verify that no nics where checked. - EXPECT_EQ(0U, nics.size()); -} - -} // namespace cricket diff --git a/webrtc/p2p/client/httpportallocator.cc b/webrtc/p2p/client/httpportallocator.cc index b36de5671d..a2d5038f90 100644 --- a/webrtc/p2p/client/httpportallocator.cc +++ b/webrtc/p2p/client/httpportallocator.cc @@ -13,10 +13,10 @@ #include #include -#include "webrtc/base/asynchttprequest.h" #include "webrtc/base/basicdefs.h" #include "webrtc/base/common.h" #include "webrtc/base/helpers.h" +#include "webrtc/base/httpcommon.h" #include "webrtc/base/logging.h" #include "webrtc/base/nethelpers.h" #include "webrtc/base/signalthread.h" @@ -144,7 +144,7 @@ void HttpPortAllocatorSessionBase::TryCreateRelaySession() { return; } - if (attempts_ == HttpPortAllocator::kNumRetries) { + if (attempts_ == HttpPortAllocatorBase::kNumRetries) { LOG(LS_ERROR) << "HttpPortAllocator: maximum number of requests reached; " << "giving up on relay."; return; @@ -167,7 +167,7 @@ void HttpPortAllocatorSessionBase::TryCreateRelaySession() { } std::string HttpPortAllocatorSessionBase::GetSessionRequestUrl() { - std::string url = std::string(HttpPortAllocator::kCreateSessionURL); + std::string url = std::string(HttpPortAllocatorBase::kCreateSessionURL); ASSERT(!username().empty()); ASSERT(!password().empty()); url = url + "?username=" + rtc::s_url_encode(username()) + @@ -220,105 +220,4 @@ void HttpPortAllocatorSessionBase::ReceiveSessionResponse( ConfigReady(config); } -// HttpPortAllocator - -HttpPortAllocator::HttpPortAllocator( - rtc::NetworkManager* network_manager, - rtc::PacketSocketFactory* socket_factory, - const std::string &user_agent) - : HttpPortAllocatorBase(network_manager, socket_factory, user_agent) { -} - -HttpPortAllocator::HttpPortAllocator( - rtc::NetworkManager* network_manager, - const std::string &user_agent) - : HttpPortAllocatorBase(network_manager, user_agent) { -} -HttpPortAllocator::~HttpPortAllocator() {} - -PortAllocatorSession* HttpPortAllocator::CreateSessionInternal( - const std::string& content_name, - int component, - const std::string& ice_ufrag, const std::string& ice_pwd) { - return new HttpPortAllocatorSession(this, content_name, component, - ice_ufrag, ice_pwd, stun_hosts(), - relay_hosts(), relay_token(), - user_agent()); -} - -// HttpPortAllocatorSession - -HttpPortAllocatorSession::HttpPortAllocatorSession( - HttpPortAllocator* allocator, - const std::string& content_name, - int component, - const std::string& ice_ufrag, - const std::string& ice_pwd, - const std::vector& stun_hosts, - const std::vector& relay_hosts, - const std::string& relay, - const std::string& agent) - : HttpPortAllocatorSessionBase(allocator, content_name, component, - ice_ufrag, ice_pwd, stun_hosts, - relay_hosts, relay, agent) { -} - -HttpPortAllocatorSession::~HttpPortAllocatorSession() { - for (std::list::iterator it = requests_.begin(); - it != requests_.end(); ++it) { - (*it)->Destroy(true); - } -} - -void HttpPortAllocatorSession::SendSessionRequest(const std::string& host, - int port) { - // Initiate an HTTP request to create a session through the chosen host. - rtc::AsyncHttpRequest* request = - new rtc::AsyncHttpRequest(user_agent()); - request->SignalWorkDone.connect(this, - &HttpPortAllocatorSession::OnRequestDone); - - request->set_secure(port == rtc::HTTP_SECURE_PORT); - request->set_proxy(allocator()->proxy()); - request->response().document.reset(new rtc::MemoryStream); - request->request().verb = rtc::HV_GET; - request->request().path = GetSessionRequestUrl(); - request->request().addHeader("X-Talk-Google-Relay-Auth", relay_token(), true); - request->request().addHeader("X-Stream-Type", "video_rtp", true); - request->set_host(host); - request->set_port(port); - request->Start(); - request->Release(); - - requests_.push_back(request); -} - -void HttpPortAllocatorSession::OnRequestDone(rtc::SignalThread* data) { - rtc::AsyncHttpRequest* request = - static_cast(data); - - // Remove the request from the list of active requests. - std::list::iterator it = - std::find(requests_.begin(), requests_.end(), request); - if (it != requests_.end()) { - requests_.erase(it); - } - - if (request->response().scode != 200) { - LOG(LS_WARNING) << "HTTPPortAllocator: request " - << " received error " << request->response().scode; - TryCreateRelaySession(); - return; - } - LOG(LS_INFO) << "HTTPPortAllocator: request succeeded"; - - rtc::MemoryStream* stream = - static_cast(request->response().document.get()); - stream->Rewind(); - size_t length; - stream->GetSize(&length); - std::string resp = std::string(stream->GetBuffer(), length); - ReceiveSessionResponse(resp); -} - } // namespace cricket diff --git a/webrtc/p2p/client/httpportallocator.h b/webrtc/p2p/client/httpportallocator.h index e2fa74354d..e52765901f 100644 --- a/webrtc/p2p/client/httpportallocator.h +++ b/webrtc/p2p/client/httpportallocator.h @@ -26,6 +26,12 @@ class SignalThread; namespace cricket { +// TODO(pthatcher): Remove this. It's only used by chromoting, so we +// should just move this code there. It's used in these places in +// chromium: +// src/remoting/protocol/chromium_port_allocator.cc +// src/remoting/client/plugin/pepper_port_allocator.cc +// src/remoting/protocol/libjingle_transport_factory.cc class HttpPortAllocatorBase : public BasicPortAllocator { public: // The number of HTTP requests we should attempt before giving up. @@ -130,44 +136,6 @@ class HttpPortAllocatorSessionBase : public BasicPortAllocatorSession { int attempts_; }; -class HttpPortAllocator : public HttpPortAllocatorBase { - public: - HttpPortAllocator(rtc::NetworkManager* network_manager, - const std::string& user_agent); - HttpPortAllocator(rtc::NetworkManager* network_manager, - rtc::PacketSocketFactory* socket_factory, - const std::string& user_agent); - virtual ~HttpPortAllocator(); - virtual PortAllocatorSession* CreateSessionInternal( - const std::string& content_name, - int component, - const std::string& ice_ufrag, const std::string& ice_pwd); -}; - -class HttpPortAllocatorSession : public HttpPortAllocatorSessionBase { - public: - HttpPortAllocatorSession( - HttpPortAllocator* allocator, - const std::string& content_name, - int component, - const std::string& ice_ufrag, - const std::string& ice_pwd, - const std::vector& stun_hosts, - const std::vector& relay_hosts, - const std::string& relay, - const std::string& agent); - virtual ~HttpPortAllocatorSession(); - - virtual void SendSessionRequest(const std::string& host, int port); - - protected: - // Protected for diagnostics. - virtual void OnRequestDone(rtc::SignalThread* request); - - private: - std::list requests_; -}; - } // namespace cricket #endif // WEBRTC_P2P_CLIENT_HTTPPORTALLOCATOR_H_ diff --git a/webrtc/p2p/client/portallocator_unittest.cc b/webrtc/p2p/client/portallocator_unittest.cc index 7a52a2eff8..9ea22dd189 100644 --- a/webrtc/p2p/client/portallocator_unittest.cc +++ b/webrtc/p2p/client/portallocator_unittest.cc @@ -1218,109 +1218,3 @@ TEST_F(PortAllocatorTest, TestEnableIPv6Addresses) { kClientAddr); EXPECT_EQ(4U, candidates_.size()); } - -// Test that the httpportallocator correctly maintains its lists of stun and -// relay servers, by never allowing an empty list. -TEST(HttpPortAllocatorTest, TestHttpPortAllocatorHostLists) { - rtc::FakeNetworkManager network_manager; - cricket::HttpPortAllocator alloc(&network_manager, "unit test agent"); - EXPECT_EQ(1U, alloc.relay_hosts().size()); - EXPECT_EQ(1U, alloc.stun_hosts().size()); - - std::vector relay_servers; - std::vector stun_servers; - - alloc.SetRelayHosts(relay_servers); - alloc.SetStunHosts(stun_servers); - EXPECT_EQ(1U, alloc.relay_hosts().size()); - EXPECT_EQ(1U, alloc.stun_hosts().size()); - - relay_servers.push_back("1.unittest.corp.google.com"); - relay_servers.push_back("2.unittest.corp.google.com"); - stun_servers.push_back( - rtc::SocketAddress("1.unittest.corp.google.com", 0)); - stun_servers.push_back( - rtc::SocketAddress("2.unittest.corp.google.com", 0)); - - alloc.SetRelayHosts(relay_servers); - alloc.SetStunHosts(stun_servers); - EXPECT_EQ(2U, alloc.relay_hosts().size()); - EXPECT_EQ(2U, alloc.stun_hosts().size()); -} - -// Test that the HttpPortAllocator uses correct URL to create sessions. -TEST(HttpPortAllocatorTest, TestSessionRequestUrl) { - rtc::FakeNetworkManager network_manager; - cricket::HttpPortAllocator alloc(&network_manager, "unit test agent"); - - rtc::scoped_ptr session( - static_cast( - alloc.CreateSessionInternal( - "test content", 0, kIceUfrag0, kIcePwd0))); - std::string url = session->GetSessionRequestUrl(); - LOG(LS_INFO) << "url: " << url; - std::vector parts; - rtc::split(url, '?', &parts); - ASSERT_EQ(2U, parts.size()); - - std::vector args_parts; - rtc::split(parts[1], '&', &args_parts); - - std::map args; - for (std::vector::iterator it = args_parts.begin(); - it != args_parts.end(); ++it) { - std::vector parts; - rtc::split(*it, '=', &parts); - ASSERT_EQ(2U, parts.size()); - args[rtc::s_url_decode(parts[0])] = rtc::s_url_decode(parts[1]); - } - - EXPECT_EQ(kIceUfrag0, args["username"]); - EXPECT_EQ(kIcePwd0, args["password"]); -} - -// Tests that destroying ports with non-shared sockets does not crash. -// b/19074679. -TEST_F(PortAllocatorTest, TestDestroyPortsNonSharedSockets) { - AddInterface(kClientAddr); - EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP)); - session_->StartGettingPorts(); - ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout); - EXPECT_EQ(4U, ports_.size()); - - auto it = ports_.begin(); - for (; it != ports_.end(); ++it) { - (reinterpret_cast(*it))->Destroy(); - } -} - -class AllocationSequenceForTest : public cricket::AllocationSequence { - public: - AllocationSequenceForTest(cricket::BasicPortAllocatorSession* session, - rtc::Network* network, - cricket::PortConfiguration* config, - uint32 flags) - : cricket::AllocationSequence(session, network, config, flags) {} - using cricket::AllocationSequence::CreateTurnPort; -}; - -TEST_F(PortAllocatorTest, TestCreateTurnPortWithNullSocket) { - EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP)); - session_->StartGettingPorts(); - - cricket::ServerAddresses stun_servers; - stun_servers.insert(kStunAddr); - cricket::PortConfiguration config(stun_servers, kIceUfrag0, kIcePwd0); - rtc::Network network1("test_eth0", "Test Network Adapter 1", - rtc::IPAddress(0x12345600U), 24); - uint32 flag = cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET; - AllocationSequenceForTest alloc_sequence( - static_cast(session_.get()), - &network1, &config, flag); - // This simply tests it will not crash if udp_socket_ in the - // AllocationSequence is null, which is chosen in the constructor. - cricket::RelayServerConfig relay_server(cricket::RELAY_TURN); - relay_server.ports.push_back( - cricket::ProtocolAddress(kTurnUdpIntAddr, cricket::PROTO_UDP, false)); - alloc_sequence.CreateTurnPort(relay_server); -} diff --git a/webrtc/p2p/p2p.gyp b/webrtc/p2p/p2p.gyp index 74546edec0..45c9e13d19 100644 --- a/webrtc/p2p/p2p.gyp +++ b/webrtc/p2p/p2p.gyp @@ -78,11 +78,8 @@ 'base/turnserver.cc', 'base/turnserver.h', 'base/udpport.h', - 'client/autoportallocator.h', 'client/basicportallocator.cc', 'client/basicportallocator.h', - 'client/connectivitychecker.cc', - 'client/connectivitychecker.h', 'client/httpportallocator.cc', 'client/httpportallocator.h', 'client/socketmonitor.cc', diff --git a/webrtc/p2p/p2p_tests.gypi b/webrtc/p2p/p2p_tests.gypi index 133e9880ff..8c2c2b35ab 100644 --- a/webrtc/p2p/p2p_tests.gypi +++ b/webrtc/p2p/p2p_tests.gypi @@ -32,7 +32,6 @@ 'base/transport_unittest.cc', 'base/transportdescriptionfactory_unittest.cc', 'base/turnport_unittest.cc', - 'client/connectivitychecker_unittest.cc', 'client/fakeportallocator.h', 'client/portallocator_unittest.cc', 'stunprober/stunprober_unittest.cc',