Commit ead49409 authored by sergeyu@chromium.org's avatar sergeyu@chromium.org

Always use chromium threads for IO in remoting host

BUG=137140


Review URL: https://chromiumcodereview.appspot.com/10808094

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148418 0039d316-1c4b-4281-b951-d872f2087c98
parent e18d4aca
......@@ -9,16 +9,15 @@
#include "base/bind.h"
#include "base/threading/thread.h"
#include "remoting/host/url_request_context.h"
#include "remoting/jingle_glue/jingle_thread.h"
namespace remoting {
ChromotingHostContext::ChromotingHostContext(
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
: capture_thread_("ChromotingCaptureThread"),
: network_thread_("ChromotingNetworkThread"),
capture_thread_("ChromotingCaptureThread"),
encode_thread_("ChromotingEncodeThread"),
desktop_thread_("ChromotingDesktopThread"),
io_thread_("ChromotingIOThread"),
file_thread_("ChromotingFileIOThread"),
ui_task_runner_(ui_task_runner) {
}
......@@ -29,24 +28,20 @@ ChromotingHostContext::~ChromotingHostContext() {
bool ChromotingHostContext::Start() {
// Start all the threads.
bool started = capture_thread_.Start() && encode_thread_.Start() &&
jingle_thread_.Start() && desktop_thread_.Start() &&
io_thread_.StartWithOptions(
base::Thread::Options(MessageLoop::TYPE_IO, 0)) &&
network_thread_.StartWithOptions(base::Thread::Options(
MessageLoop::TYPE_IO, 0)) &&
desktop_thread_.Start() &&
file_thread_.StartWithOptions(
base::Thread::Options(MessageLoop::TYPE_IO, 0));
if (!started)
return false;
url_request_context_getter_ = new URLRequestContextGetter(
ui_task_runner(), io_task_runner(),
ui_task_runner(), network_task_runner(),
static_cast<MessageLoopForIO*>(file_thread_.message_loop()));
return true;
}
JingleThread* ChromotingHostContext::jingle_thread() {
return &jingle_thread_;
}
base::SingleThreadTaskRunner* ChromotingHostContext::capture_task_runner() {
return capture_thread_.message_loop_proxy();
}
......@@ -56,7 +51,7 @@ base::SingleThreadTaskRunner* ChromotingHostContext::encode_task_runner() {
}
base::SingleThreadTaskRunner* ChromotingHostContext::network_task_runner() {
return jingle_thread_.message_loop_proxy();
return network_thread_.message_loop_proxy();
}
base::SingleThreadTaskRunner* ChromotingHostContext::desktop_task_runner() {
......@@ -67,10 +62,6 @@ base::SingleThreadTaskRunner* ChromotingHostContext::ui_task_runner() {
return ui_task_runner_;
}
base::SingleThreadTaskRunner* ChromotingHostContext::io_task_runner() {
return io_thread_.message_loop_proxy();
}
base::SingleThreadTaskRunner* ChromotingHostContext::file_task_runner() {
return file_thread_.message_loop_proxy();
}
......
......@@ -11,7 +11,6 @@
#include "base/memory/ref_counted.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread.h"
#include "remoting/jingle_glue/jingle_thread.h"
namespace base {
class SingleThreadTaskRunner;
......@@ -39,8 +38,6 @@ class ChromotingHostContext {
// this API.
virtual bool Start();
virtual JingleThread* jingle_thread();
// Task runner for the thread that is used for the UI. In the NPAPI
// plugin this corresponds to the main plugin thread.
virtual base::SingleThreadTaskRunner* ui_task_runner();
......@@ -63,18 +60,6 @@ class ChromotingHostContext {
// Can we use some other thread instead?
virtual base::SingleThreadTaskRunner* desktop_task_runner();
// Task runner for the thread that is used for chromium's network
// IO, particularly all HTTP requests (for OAuth and Relay servers).
// Chromium's HTTP stack cannot be used on the network_task_runner()
// because that thread runs libjingle's message loop, while
// chromium's sockets must be used on a thread with a
// MessageLoopForIO.
//
// TODO(sergeyu): Implement socket server for libjingle that works
// on a regular chromium thread and use it for network_task_runner()
// to avoid the need for io_task_runner().
virtual base::SingleThreadTaskRunner* io_task_runner();
// Task runner for the thread that is used for blocking file
// IO. This thread is used by the URLRequestContext to read proxy
// configuration and by NatConfig to read policy configs.
......@@ -87,7 +72,7 @@ class ChromotingHostContext {
FRIEND_TEST_ALL_PREFIXES(ChromotingHostContextTest, StartAndStop);
// A thread that hosts all network operations.
JingleThread jingle_thread_;
base::Thread network_thread_;
// A thread that hosts screen capture.
base::Thread capture_thread_;
......@@ -98,9 +83,6 @@ class ChromotingHostContext {
// A thread that hosts input injection.
base::Thread desktop_thread_;
// Thread for non-blocking IO operations.
base::Thread io_thread_;
// Thread for blocking IO operations.
base::Thread file_thread_;
......
......@@ -16,7 +16,7 @@ TEST(ChromotingHostContextTest, StartAndStop) {
ChromotingHostContext context(base::MessageLoopProxy::current());
context.Start();
EXPECT_TRUE(context.jingle_thread());
EXPECT_TRUE(context.network_task_runner());
EXPECT_TRUE(context.capture_task_runner());
EXPECT_TRUE(context.encode_task_runner());
}
......
......@@ -16,7 +16,6 @@
#include "remoting/host/constants.h"
#include "remoting/host/server_log_entry.h"
#include "remoting/jingle_glue/iq_sender.h"
#include "remoting/jingle_glue/jingle_thread.h"
#include "remoting/jingle_glue/signal_strategy.h"
#include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
#include "third_party/libjingle/source/talk/xmpp/constants.h"
......
......@@ -87,7 +87,6 @@ class MockChromotingHostContext : public ChromotingHostContext {
MOCK_METHOD0(Start, bool());
MOCK_METHOD0(Stop, void());
MOCK_METHOD0(jingle_thread, JingleThread*());
MOCK_METHOD0(ui_task_runner, base::SingleThreadTaskRunner*());
MOCK_METHOD0(capture_task_runner, base::SingleThreadTaskRunner*());
MOCK_METHOD0(encode_task_runner, base::SingleThreadTaskRunner*());
......
......@@ -13,7 +13,7 @@
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_context_getter.h"
#include "remoting/host/network_settings.h"
#include "third_party/libjingle/source/talk/base/basicpacketsocketfactory.h"
#include "remoting/jingle_glue/chromium_socket_factory.h"
namespace remoting {
......@@ -128,7 +128,7 @@ scoped_ptr<HostPortAllocator> HostPortAllocator::Create(
scoped_ptr<talk_base::NetworkManager> network_manager(
new talk_base::BasicNetworkManager());
scoped_ptr<talk_base::PacketSocketFactory> socket_factory(
new talk_base::BasicPacketSocketFactory());
new remoting::ChromiumPacketSocketFactory());
scoped_ptr<HostPortAllocator> result(
new HostPortAllocator(url_context, network_manager.Pass(),
socket_factory.Pass()));
......
......@@ -10,7 +10,6 @@
#include "remoting/host/chromoting_host.h"
#include "remoting/host/server_log_entry.h"
#include "remoting/jingle_glue/iq_sender.h"
#include "remoting/jingle_glue/jingle_thread.h"
#include "remoting/jingle_glue/signal_strategy.h"
#include "remoting/protocol/transport.h"
#include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
......
......@@ -549,8 +549,8 @@ void HostNPScriptObject::FinishConnectNetworkThread(
// Create XMPP connection.
scoped_ptr<SignalStrategy> signal_strategy(
new XmppSignalStrategy(host_context_->jingle_thread(), uid,
auth_token, auth_service));
new XmppSignalStrategy(host_context_->url_request_context_getter(),
uid, auth_token, auth_service));
// Request registration of the host for support.
scoped_ptr<RegisterSupportHostRequest> register_request(
......
......@@ -12,7 +12,6 @@
#include "remoting/base/constants.h"
#include "remoting/host/host_config.h"
#include "remoting/jingle_glue/iq_sender.h"
#include "remoting/jingle_glue/jingle_thread.h"
#include "remoting/jingle_glue/signal_strategy.h"
#include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
#include "third_party/libjingle/source/talk/xmpp/constants.h"
......
......@@ -357,8 +357,9 @@ class HostProcess
if (!signal_strategy_.get()) {
signal_strategy_.reset(
new XmppSignalStrategy(context_->jingle_thread(), xmpp_login_,
xmpp_auth_token_, xmpp_auth_service_));
new XmppSignalStrategy(context_->url_request_context_getter(),
xmpp_login_, xmpp_auth_token_,
xmpp_auth_service_));
signaling_connector_.reset(new SignalingConnector(
signal_strategy_.get(),
......
......@@ -217,9 +217,9 @@ class SimpleHost : public HeartbeatSender::Listener {
}
void StartHost() {
signal_strategy_.reset(
new XmppSignalStrategy(context_.jingle_thread(), xmpp_login_,
xmpp_auth_token_, xmpp_auth_service_));
signal_strategy_.reset(new XmppSignalStrategy(
context_.url_request_context_getter(),
xmpp_login_, xmpp_auth_token_, xmpp_auth_service_));
signaling_connector_.reset(new SignalingConnector(
signal_strategy_.get(),
base::Bind(&SimpleHost::OnAuthFailed, base::Unretained(this))));
......
......@@ -8,6 +8,7 @@
#include "net/base/cert_verifier.h"
#include "net/base/host_resolver.h"
#include "net/base/ssl_config_service_defaults.h"
#include "net/base/transport_security_state.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_network_layer.h"
#include "net/http/http_network_session.h"
......@@ -93,6 +94,7 @@ URLRequestContext::URLRequestContext(
storage_.set_http_auth_handler_factory(
net::HttpAuthHandlerFactory::CreateDefault(host_resolver()));
storage_.set_http_server_properties(new net::HttpServerPropertiesImpl);
storage_.set_transport_security_state(new net::TransportSecurityState);
net::HttpNetworkSession::Params session_params;
session_params.host_resolver = host_resolver();
......
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/jingle_glue/jingle_thread.h"
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/message_loop_proxy.h"
#include "base/message_pump.h"
#include "base/time.h"
#include "third_party/libjingle/source/talk/base/ssladapter.h"
namespace remoting {
const uint32 kRunTasksMessageId = 1;
const uint32 kStopMessageId = 2;
namespace {
class JingleMessagePump : public base::MessagePump,
public talk_base::MessageHandler {
public:
JingleMessagePump(talk_base::Thread* thread)
: thread_(thread), delegate_(NULL), stopping_(false) {
}
virtual void Run(Delegate* delegate) {
delegate_ = delegate;
thread_->Thread::Run();
// Call Restart() so that we can run again.
thread_->Restart();
delegate_ = NULL;
}
virtual void Quit() {
if (!stopping_) {
stopping_ = true;
// Shutdown gracefully: make sure that we excute all messages
// left in the queue before exiting. Thread::Quit() would not do
// that.
thread_->Post(this, kStopMessageId);
}
}
virtual void ScheduleWork() {
thread_->Post(this, kRunTasksMessageId);
}
virtual void ScheduleDelayedWork(const base::TimeTicks& time) {
delayed_work_time_ = time;
ScheduleNextDelayedTask();
}
void OnMessage(talk_base::Message* msg) {
if (msg->message_id == kRunTasksMessageId) {
DCHECK(delegate_);
// Clear currently pending messages in case there were delayed tasks.
// Will schedule it again from ScheduleNextDelayedTask() if neccessary.
thread_->Clear(this, kRunTasksMessageId);
// Process all pending tasks.
while (true) {
if (delegate_->DoWork())
continue;
if (delegate_->DoDelayedWork(&delayed_work_time_))
continue;
if (delegate_->DoIdleWork())
continue;
break;
}
ScheduleNextDelayedTask();
} else if (msg->message_id == kStopMessageId) {
DCHECK(stopping_);
// Stop the thread only if there are no more non-delayed
// messages left in the queue, otherwise post another task to
// try again later.
int delay = thread_->GetDelay();
if (delay > 0 || delay == talk_base::kForever) {
stopping_ = false;
thread_->Quit();
} else {
thread_->Post(this, kStopMessageId);
}
} else {
NOTREACHED();
}
}
protected:
virtual ~JingleMessagePump() {}
private:
void ScheduleNextDelayedTask() {
if (!delayed_work_time_.is_null()) {
base::TimeTicks now = base::TimeTicks::Now();
int delay = static_cast<int>((delayed_work_time_ - now).InMilliseconds());
if (delay > 0) {
thread_->PostDelayed(delay, this, kRunTasksMessageId);
} else {
thread_->Post(this, kRunTasksMessageId);
}
}
}
talk_base::Thread* thread_;
Delegate* delegate_;
base::TimeTicks delayed_work_time_;
bool stopping_;
};
} // namespace
JingleThreadMessageLoop::JingleThreadMessageLoop(talk_base::Thread* thread)
: MessageLoop(MessageLoop::TYPE_IO) {
pump_ = new JingleMessagePump(thread);
}
JingleThreadMessageLoop::~JingleThreadMessageLoop() {
}
TaskPump::TaskPump() {
}
void TaskPump::WakeTasks() {
talk_base::Thread::Current()->Post(this);
}
int64 TaskPump::CurrentTime() {
return static_cast<int64>(talk_base::Time());
}
void TaskPump::OnMessage(talk_base::Message* pmsg) {
RunTasks();
}
JingleThread::JingleThread()
: task_pump_(NULL),
started_event_(true, false),
stopped_event_(true, false),
message_loop_(NULL) {
}
JingleThread::~JingleThread() {
// It is important to call Stop here. If we wait for the base class to
// call Stop in its d'tor, then JingleThread::Run() will access member
// variables that are already gone. See similar comments in
// base/threading/thread.h.
if (message_loop_)
Stop();
}
bool JingleThread::Start() {
if (!Thread::Start())
return false;
started_event_.Wait();
return true;
}
void JingleThread::Run() {
JingleThreadMessageLoop message_loop(this);
message_loop_ = &message_loop;
message_loop_proxy_ = base::MessageLoopProxy::current();
TaskPump task_pump;
task_pump_ = &task_pump;
// Signal after we've initialized |message_loop_| and |task_pump_|.
started_event_.Signal();
message_loop.Run();
stopped_event_.Signal();
task_pump_ = NULL;
message_loop_ = NULL;
}
void JingleThread::Stop() {
message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
stopped_event_.Wait();
// This will wait until the thread is actually finished.
Thread::Stop();
}
MessageLoop* JingleThread::message_loop() {
return message_loop_;
}
base::MessageLoopProxy* JingleThread::message_loop_proxy() {
return message_loop_proxy_;
}
TaskPump* JingleThread::task_pump() {
return task_pump_;
}
} // namespace remoting
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef REMOTING_JINGLE_GLUE_JINGLE_THREAD_H_
#define REMOTING_JINGLE_GLUE_JINGLE_THREAD_H_
#include "base/message_loop.h"
#include "base/tracked_objects.h"
#include "base/synchronization/waitable_event.h"
#include "third_party/libjingle/source/talk/base/messagequeue.h"
#include "third_party/libjingle/source/talk/base/taskrunner.h"
#include "third_party/libjingle/source/talk/base/thread.h"
namespace base {
class MessageLoopProxy;
} // namespace base
namespace remoting {
class TaskPump : public talk_base::MessageHandler,
public talk_base::TaskRunner {
public:
TaskPump();
// TaskRunner methods.
virtual void WakeTasks() OVERRIDE;
virtual int64 CurrentTime() OVERRIDE;
// MessageHandler methods.
virtual void OnMessage(talk_base::Message* pmsg) OVERRIDE;
};
class JingleThreadMessageLoop : public MessageLoop {
public:
explicit JingleThreadMessageLoop(talk_base::Thread* thread);
virtual ~JingleThreadMessageLoop();
private:
DISALLOW_COPY_AND_ASSIGN(JingleThreadMessageLoop);
};
// TODO(sergeyu): This class should be changed to inherit from Chromiums
// base::Thread instead of libjingle's thread.
class JingleThread : public talk_base::Thread {
public:
JingleThread();
virtual ~JingleThread();
bool Start();
// Main function for the thread. Should not be called directly.
virtual void Run() OVERRIDE;
// Stop the thread.
virtual void Stop() OVERRIDE;
// Returns Chromiums message loop for this thread.
MessageLoop* message_loop();
base::MessageLoopProxy* message_loop_proxy();
// Returns task pump if the thread is running, otherwise NULL is returned.
TaskPump* task_pump();
private:
TaskPump* task_pump_;
base::WaitableEvent started_event_;
base::WaitableEvent stopped_event_;
MessageLoop* message_loop_;
scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
DISALLOW_COPY_AND_ASSIGN(JingleThread);
};
} // namespace remoting
#endif // REMOTING_JINGLE_GLUE_JINGLE_THREAD_H_
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/message_loop.h"
#include "base/time.h"
#include "base/synchronization/waitable_event.h"
#include "remoting/jingle_glue/jingle_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace remoting {
class MockCallback {
public:
MOCK_METHOD0(Run, void());
};
namespace {
// Delay used to test delayed tasks. Shouldn't be too big, so that we don't
// slow down the test, yet, should be big enough to be measurable.
int kDelayMs = 50; // 0.05 s.
int kDelayTimeoutMs = 10000; // 10 s.
} // namespace
TEST(JingleThreadTest, PostTask) {
JingleThread thread;
MockCallback task;
EXPECT_CALL(task, Run());
thread.Start();
thread.message_loop()->PostTask(
FROM_HERE, base::Bind(&MockCallback::Run, base::Unretained(&task)));
thread.Stop();
}
TEST(JingleThreadTest, PostNonNestableTask) {
JingleThread thread;
MockCallback task;
EXPECT_CALL(task, Run());
thread.Start();
thread.message_loop()->PostNonNestableTask(
FROM_HERE, base::Bind(&MockCallback::Run, base::Unretained(&task)));
thread.Stop();
}
ACTION_P(SignalEvent, event) {
event->Signal();
}
TEST(JingleThreadTest, PostDelayedTask) {
JingleThread thread;
MockCallback task;
base::WaitableEvent event(true, false);
EXPECT_CALL(task, Run()).WillOnce(SignalEvent(&event));
thread.Start();
base::Time start = base::Time::Now();
thread.message_loop()->PostDelayedTask(
FROM_HERE, base::Bind(&MockCallback::Run, base::Unretained(&task)),
base::TimeDelta::FromMilliseconds(kDelayMs));
event.TimedWait(base::TimeDelta::FromMilliseconds(kDelayTimeoutMs));
base::Time end = base::Time::Now();
thread.Stop();
EXPECT_GE((end - start).InMillisecondsRoundedUp(), kDelayMs);
}
TEST(JingleThreadTest, PostNonNestableDelayedTask) {
JingleThread thread;
MockCallback task;
base::WaitableEvent event(true, false);
EXPECT_CALL(task, Run()).WillOnce(SignalEvent(&event));
thread.Start();
base::Time start = base::Time::Now();
thread.message_loop()->PostNonNestableDelayedTask(
FROM_HERE, base::Bind(&MockCallback::Run, base::Unretained(&task)),
base::TimeDelta::FromMilliseconds(kDelayMs));
event.TimedWait(base::TimeDelta::FromMilliseconds(kDelayTimeoutMs));
base::Time end = base::Time::Now();
thread.Stop();
EXPECT_GE((end - start).InMillisecondsRoundedUp(), kDelayMs);
}
} // namespace remoting
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/jingle_glue/ssl_adapter.h"
#if defined(OS_WIN)
#include "third_party/libjingle/source/talk/base/ssladapter.h"
#else
#include "remoting/jingle_glue/ssl_socket_adapter.h"
#endif
namespace remoting {
talk_base::SSLAdapter* CreateSSLAdapter(talk_base::AsyncSocket* socket) {
talk_base::SSLAdapter* ssl_adapter =
remoting::SSLSocketAdapter::Create(socket);
DCHECK(ssl_adapter);
return ssl_adapter;
}
} // namespace remoting
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef REMOTING_JINGLE_GLUE_SSL_ADAPTER_H_
#define REMOTING_JINGLE_GLUE_SSL_ADAPTER_H_
namespace talk_base {
class AsyncSocket;
class SSLAdapter;
} // namespace talk_base
namespace remoting {
// Wraps the given socket in a platform-dependent SSLAdapter
// implementation.
talk_base::SSLAdapter* CreateSSLAdapter(talk_base::AsyncSocket* socket);
// Utility template class that overrides CreateSSLAdapter() to use the
// above function.
template <class SocketFactory>
class SSLAdapterSocketFactory : public SocketFactory {
public:
virtual talk_base::SSLAdapter* CreateSSLAdapter(
talk_base::AsyncSocket* socket) {
return ::remoting::CreateSSLAdapter(socket);
}
};
} // namespace remoting
#endif // REMOTING_JINGLE_GLUE_SSL_ADAPTER_H_
This diff is collapsed.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef REMOTING_JINGLE_GLUE_SSL_SOCKET_ADAPTER_H_
#define REMOTING_JINGLE_GLUE_SSL_SOCKET_ADAPTER_H_
#include "base/memory/scoped_ptr.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/net_log.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/stream_socket.h"
#include "third_party/libjingle/source/talk/base/asyncsocket.h"
#include "third_party/libjingle/source/talk/base/ssladapter.h"
namespace net {
class CertVerifier;
class TransportSecurityState;
} // namespace net
namespace remoting {
class SSLSocketAdapter;
// TODO(sergeyu): Write unittests for this code!
// This class provides a wrapper to libjingle's talk_base::AsyncSocket that
// implements Chromium's net::StreamSocket interface. It's used by
// SSLSocketAdapter to enable Chromium's SSL implementation to work over
// libjingle's socket class.
class TransportSocket : public net::StreamSocket, public sigslot::has_slots<> {
public:
TransportSocket(talk_base::AsyncSocket* socket,
SSLSocketAdapter *ssl_adapter);
virtual ~TransportSocket();
void set_addr(const talk_base::SocketAddress& addr) {
addr_ = addr;
}
// net::StreamSocket implementation.
virtual int Connect(const net::CompletionCallback& callback) OVERRIDE;
virtual void Disconnect() OVERRIDE;
virtual bool IsConnected() const OVERRIDE;
virtual bool IsConnectedAndIdle() const OVERRIDE;
virtual int GetPeerAddress(net::IPEndPoint* address) const OVERRIDE;
virtual int GetLocalAddress(net::IPEndPoint* address) const OVERRIDE;
virtual const net::BoundNetLog& NetLog() const OVERRIDE;
virtual void SetSubresourceSpeculation() OVERRIDE;
virtual void SetOmniboxSpeculation() OVERRIDE;
virtual bool WasEverUsed() const OVERRIDE;
virtual bool UsingTCPFastOpen() const OVERRIDE;
virtual int64 NumBytesRead() const OVERRIDE;
virtual base::TimeDelta GetConnectTimeMicros() const OVERRIDE;
virtual bool WasNpnNegotiated() const OVERRIDE;
virtual net::NextProto GetNegotiatedProtocol() const OVERRIDE;
virtual bool GetSSLInfo(net::SSLInfo* ssl_info) OVERRIDE;
// net::Socket implementation.
virtual int Read(net::IOBuffer* buf, int buf_len,
const net::CompletionCallback& callback) OVERRIDE;
virtual int Write(net::IOBuffer* buf, int buf_len,
const net::CompletionCallback& callback) OVERRIDE;
virtual bool SetReceiveBufferSize(int32 size) OVERRIDE;
virtual bool SetSendBufferSize(int32 size) OVERRIDE;
private:
friend class SSLSocketAdapter;
void OnReadEvent(talk_base::AsyncSocket* socket);
void OnWriteEvent(talk_base::AsyncSocket* socket);
// Holds the user's completion callback when Write and Read are called.
net::CompletionCallback read_callback_;
net::CompletionCallback write_callback_;
scoped_refptr<net::IOBuffer> read_buffer_;
int read_buffer_len_;
scoped_refptr<net::IOBuffer> write_buffer_;
int write_buffer_len_;
net::BoundNetLog net_log_;
talk_base::AsyncSocket *socket_;
talk_base::SocketAddress addr_;
bool was_used_to_convey_data_;
DISALLOW_COPY_AND_ASSIGN(TransportSocket);
};
// This provides a talk_base::AsyncSocketAdapter interface around Chromium's
// net::SSLClientSocket class. This allows remoting to use Chromium's SSL
// implementation instead of OpenSSL.
class SSLSocketAdapter : public talk_base::SSLAdapter {
public:
explicit SSLSocketAdapter(talk_base::AsyncSocket* socket);
virtual ~SSLSocketAdapter();
// StartSSL returns 0 if successful, or non-zero on failure.
// If StartSSL is called while the socket is closed or connecting, the SSL
// negotiation will begin as soon as the socket connects.
//
// restartable is not implemented, and must be set to false.
virtual int StartSSL(const char* hostname, bool restartable) OVERRIDE;
// Create the default SSL adapter for this platform.
static SSLSocketAdapter* Create(AsyncSocket* socket);
virtual int Send(const void* pv, size_t cb) OVERRIDE;
virtual int Recv(void* pv, size_t cb) OVERRIDE;
private:
friend class TransportSocket;
enum SSLState {
SSLSTATE_NONE,
SSLSTATE_WAIT,
SSLSTATE_CONNECTED,
SSLSTATE_ERROR,
};
void OnConnected(int result);
void OnRead(int result);
void OnWritten(int result);
void DoWrite();
virtual void OnConnectEvent(talk_base::AsyncSocket* socket) OVERRIDE;
int BeginSSL();
bool ignore_bad_cert_;
std::string hostname_;
TransportSocket* transport_socket_;
// |cert_verifier_| must be defined before |ssl_socket_|, so that
// it's destroyed after |ssl_socket_|.
scoped_ptr<net::CertVerifier> cert_verifier_;
scoped_ptr<net::TransportSecurityState> transport_security_state_;
scoped_ptr<net::SSLClientSocket> ssl_socket_;
SSLState ssl_state_;
bool read_pending_;
scoped_refptr<net::GrowableIOBuffer> read_buffer_;
bool write_pending_;
scoped_refptr<net::DrainableIOBuffer> write_buffer_;
DISALLOW_COPY_AND_ASSIGN(SSLSocketAdapter);
};
} // namespace remoting
#endif // REMOTING_JINGLE_GLUE_SSL_SOCKET_ADAPTER_H_
......@@ -7,10 +7,13 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "jingle/glue/chrome_async_socket.h"
#include "jingle/glue/task_pump.h"
#include "jingle/glue/xmpp_client_socket_factory.h"
#include "jingle/notifier/base/gaia_token_pre_xmpp_auth.h"
#include "remoting/jingle_glue/jingle_thread.h"
#include "remoting/jingle_glue/xmpp_socket_adapter.h"
#include "third_party/libjingle/source/talk/base/asyncsocket.h"
#include "net/socket/client_socket_factory.h"
#include "net/url_request/url_request_context_getter.h"
#include "third_party/libjingle/source/talk/base/thread.h"
#include "third_party/libjingle/source/talk/xmpp/prexmppauth.h"
#include "third_party/libjingle/source/talk/xmpp/saslcookiemechanism.h"
......@@ -22,6 +25,11 @@ const char kDefaultResourceName[] = "chromoting";
// connections that are idle for more than a minute.
const int kKeepAliveIntervalSeconds = 50;
// Read buffer size used by ChromeAsyncSocket for read and write buffers. Most
// of XMPP messages are smaller than 4kB.
const size_t kReadBufferSize = 4096;
const size_t kWriteBufferSize = 4096;
void DisconnectXmppClient(buzz::XmppClient* client) {
client->Disconnect();
}
......@@ -30,11 +38,12 @@ void DisconnectXmppClient(buzz::XmppClient* client) {
namespace remoting {
XmppSignalStrategy::XmppSignalStrategy(JingleThread* jingle_thread,
const std::string& username,
const std::string& auth_token,
const std::string& auth_token_service)
: thread_(jingle_thread),
XmppSignalStrategy::XmppSignalStrategy(
scoped_refptr<net::URLRequestContextGetter> request_context_getter,
const std::string& username,
const std::string& auth_token,
const std::string& auth_token_service)
: request_context_getter_(request_context_getter),
username_(username),
auth_token_(auth_token),
auth_token_service_(auth_token_service),
......@@ -64,9 +73,15 @@ void XmppSignalStrategy::Connect() {
settings.set_auth_token(buzz::AUTH_MECHANISM_GOOGLE_TOKEN, auth_token_);
settings.set_server(talk_base::SocketAddress("talk.google.com", 5222));
buzz::AsyncSocket* socket = new XmppSocketAdapter(settings, false);
scoped_ptr<jingle_glue::XmppClientSocketFactory> socket_factory(
new jingle_glue::XmppClientSocketFactory(
net::ClientSocketFactory::GetDefaultFactory(),
net::SSLConfig(), request_context_getter_, false));
buzz::AsyncSocket* socket = new jingle_glue::ChromeAsyncSocket(
socket_factory.release(), kReadBufferSize, kWriteBufferSize);
xmpp_client_ = new buzz::XmppClient(thread_->task_pump());
task_runner_.reset(new jingle_glue::TaskPump());
xmpp_client_ = new buzz::XmppClient(task_runner_.get());
xmpp_client_->Connect(settings, "", socket, CreatePreXmppAuth(settings));
xmpp_client_->SignalStateChange.connect(
this, &XmppSignalStrategy::OnConnectionStateChanged);
......
......@@ -21,6 +21,14 @@
#include "third_party/libjingle/source/talk/base/sigslot.h"
#include "third_party/libjingle/source/talk/xmpp/xmppclient.h"
namespace net {
class URLRequestContextGetter;
} // namespace net
namespace talk_base {
class TaskRunner;
} // namespace talk_base
namespace remoting {
class JingleThread;
......@@ -30,10 +38,11 @@ class XmppSignalStrategy : public base::NonThreadSafe,
public buzz::XmppStanzaHandler,
public sigslot::has_slots<> {
public:
XmppSignalStrategy(JingleThread* thread,
const std::string& username,
const std::string& auth_token,
const std::string& auth_token_service);
XmppSignalStrategy(
scoped_refptr<net::URLRequestContextGetter> request_context_getter,
const std::string& username,
const std::string& auth_token,
const std::string& auth_token_service);
virtual ~XmppSignalStrategy();
// SignalStrategy interface.
......@@ -70,12 +79,12 @@ class XmppSignalStrategy : public base::NonThreadSafe,
void SendKeepAlive();
JingleThread* thread_;
scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
std::string username_;
std::string auth_token_;
std::string auth_token_service_;
std::string resource_name_;
scoped_ptr<talk_base::TaskRunner> task_runner_;
buzz::XmppClient* xmpp_client_;
State state_;
......
This diff is collapsed.
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef REMOTING_JINGLE_GLUE_XMPP_SOCKET_ADAPTER_H_
#define REMOTING_JINGLE_GLUE_XMPP_SOCKET_ADAPTER_H_
#include <string>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "third_party/libjingle/source/talk/base/asyncsocket.h"
#include "third_party/libjingle/source/talk/xmpp/asyncsocket.h"
#include "third_party/libjingle/source/talk/xmpp/xmppclientsettings.h"
#include "third_party/libjingle/source/talk/xmpp/xmppengine.h"
#ifndef _WIN32
// Additional errors used by us from Win32 headers.
#define SEC_E_CERT_EXPIRED static_cast<int>(0x80090328L)
#define WSA_NOT_ENOUGH_MEMORY ENOMEM
#endif
namespace remoting {
class XmppSocketAdapter : public buzz::AsyncSocket,
public sigslot::has_slots<> {
public:
XmppSocketAdapter(const buzz::XmppClientSettings& xcs,
bool allow_unverified_certs);
virtual ~XmppSocketAdapter();
virtual State state() OVERRIDE;
virtual Error error() OVERRIDE;
virtual int GetError() OVERRIDE;
void set_firewall(bool firewall) { firewall_ = firewall; }
virtual bool Connect(const talk_base::SocketAddress& addr) OVERRIDE;
virtual bool Read(char* data, size_t len, size_t* len_read) OVERRIDE;
virtual bool Write(const char* data, size_t len) OVERRIDE;
virtual bool Close() OVERRIDE;
#if defined(FEATURE_ENABLE_SSL)
virtual bool StartTls(const std::string& domainname) OVERRIDE;
bool IsOpen() const { return state_ == STATE_OPEN
|| state_ == STATE_TLS_OPEN; }
#else
bool IsOpen() const { return state_ == STATE_OPEN; }
#endif
sigslot::signal0<> SignalAuthenticationError;
private:
// Return false if the socket is closed.
bool HandleReadable();
bool HandleWritable();
State state_;
Error error_;
int wsa_error_;
talk_base::AsyncSocket* socket_;
cricket::ProtocolType protocol_;
talk_base::ProxyInfo proxy_;
bool firewall_;
char* write_buffer_;
size_t write_buffer_length_;
size_t write_buffer_capacity_;
bool allow_unverified_certs_;
bool FreeState();
void NotifyClose();
void OnReadEvent(talk_base::AsyncSocket* socket);
void OnWriteEvent(talk_base::AsyncSocket* socket);
void OnConnectEvent(talk_base::AsyncSocket* socket);
void OnCloseEvent(talk_base::AsyncSocket* socket, int error);
void QueueWriteData(const char* data, size_t len);
void FlushWriteQueue(Error* error, int* wsa_error);
void SetError(Error error);
void SetWSAError(int error);
DISALLOW_COPY_AND_ASSIGN(XmppSocketAdapter);
};
} // namespace remoting
#endif // REMOTING_JINGLE_GLUE_XMPP_SOCKET_ADAPTER_H_
......@@ -17,7 +17,6 @@
#include "remoting/protocol/fake_authenticator.h"
#include "remoting/protocol/jingle_session_manager.h"
#include "remoting/protocol/libjingle_transport_factory.h"
#include "remoting/jingle_glue/jingle_thread.h"
#include "remoting/jingle_glue/fake_signal_strategy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -89,9 +88,7 @@ class MockStreamChannelCallback {
class JingleSessionTest : public testing::Test {
public:
JingleSessionTest() {
talk_base::ThreadManager::Instance()->WrapCurrentThread();
message_loop_.reset(
new JingleThreadMessageLoop(talk_base::Thread::Current()));
message_loop_.reset(new MessageLoopForIO());
}
// Helper method that handles OnIncomingSession().
......@@ -257,7 +254,7 @@ class JingleSessionTest : public testing::Test {
.Times(AtLeast(1));
}
scoped_ptr<JingleThreadMessageLoop> message_loop_;
scoped_ptr<MessageLoopForIO> message_loop_;
scoped_ptr<FakeSignalStrategy> host_signal_strategy_;
scoped_ptr<FakeSignalStrategy> client_signal_strategy_;
......
......@@ -8,12 +8,13 @@
#include "base/thread_task_runner_handle.h"
#include "jingle/glue/channel_socket_adapter.h"
#include "jingle/glue/pseudotcp_adapter.h"
#include "jingle/glue/thread_wrapper.h"
#include "jingle/glue/utils.h"
#include "net/base/net_errors.h"
#include "remoting/base/constants.h"
#include "remoting/protocol/channel_authenticator.h"
#include "remoting/protocol/transport_config.h"
#include "third_party/libjingle/source/talk/base/basicpacketsocketfactory.h"
#include "remoting/jingle_glue/chromium_socket_factory.h"
#include "third_party/libjingle/source/talk/base/network.h"
#include "third_party/libjingle/source/talk/p2p/base/constants.h"
#include "third_party/libjingle/source/talk/p2p/base/p2ptransportchannel.h"
......@@ -311,15 +312,17 @@ LibjingleTransportFactory::LibjingleTransportFactory(
: http_port_allocator_(port_allocator.get()),
port_allocator_(port_allocator.Pass()),
incoming_only_(incoming_only) {
jingle_glue::JingleThreadWrapper::EnsureForCurrentThread();
}
LibjingleTransportFactory::LibjingleTransportFactory()
: network_manager_(new talk_base::BasicNetworkManager()),
socket_factory_(new talk_base::BasicPacketSocketFactory()),
socket_factory_(new remoting::ChromiumPacketSocketFactory()),
http_port_allocator_(NULL),
port_allocator_(new cricket::BasicPortAllocator(
network_manager_.get(), socket_factory_.get())),
incoming_only_(false) {
jingle_glue::JingleThreadWrapper::EnsureForCurrentThread();
}
LibjingleTransportFactory::~LibjingleTransportFactory() {
......
......@@ -30,7 +30,7 @@ class LibjingleTransportFactory : public TransportFactory {
scoped_ptr<cricket::HttpPortAllocatorBase> port_allocator,
bool incoming_only);
// Creates BasicNetworkManager, BasicPacketSocketFactory and
// Creates BasicNetworkManager, ChromiumPacketSocketFactory and
// BasicPortAllocator.
LibjingleTransportFactory();
......
......@@ -1496,18 +1496,10 @@
'jingle_glue/javascript_signal_strategy.h',
'jingle_glue/jingle_info_request.cc',
'jingle_glue/jingle_info_request.h',
'jingle_glue/jingle_thread.cc',
'jingle_glue/jingle_thread.h',
'jingle_glue/signal_strategy.h',
'jingle_glue/ssl_adapter.h',
'jingle_glue/ssl_adapter.cc',
'jingle_glue/ssl_socket_adapter.cc',
'jingle_glue/ssl_socket_adapter.h',
'jingle_glue/xmpp_proxy.h',
'jingle_glue/xmpp_signal_strategy.cc',
'jingle_glue/xmpp_signal_strategy.h',
'jingle_glue/xmpp_socket_adapter.cc',
'jingle_glue/xmpp_socket_adapter.h',
],
}, # end of target 'remoting_jingle_glue'
......@@ -1725,7 +1717,6 @@
'jingle_glue/fake_signal_strategy.cc',
'jingle_glue/fake_signal_strategy.h',
'jingle_glue/iq_sender_unittest.cc',
'jingle_glue/jingle_thread_unittest.cc',
'jingle_glue/mock_objects.cc',
'jingle_glue/mock_objects.h',
'protocol/authenticator_test_base.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment