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

Implement ChannelMultiplexer.

ChannelMultiplexer allows multiple logical channels to share a 
single underlying transport channel.

BUG=137135

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@150484 0039d316-1c4b-4281-b951-d872f2087c98
parent d7f7f753
......@@ -4,6 +4,7 @@
#include "remoting/host/server_log_entry.h"
#include "base/logging.h"
#include "base/sys_info.h"
#include "remoting/base/constants.h"
#include "remoting/protocol/session.h"
......
......@@ -15,6 +15,7 @@
'control.proto',
'event.proto',
'internal.proto',
'mux.proto',
'video.proto',
],
'variables': {
......
// 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.
//
// Protocol for the mux channel that multiplexes multiple channels.
syntax = "proto2";
option optimize_for = LITE_RUNTIME;
package remoting.protocol;
message MultiplexPacket {
// Channel ID. Each peer choses this value when it sends first packet to
// the other peer. It unique identified channel this packet belongs to.
// Channel ID is direction-specific, i.e. each channel has two IDs
// assigned to it: one for receiving and one for sending.
optional int32 channel_id = 1;
// Channel name. The name is used to identify channels before channel ID
// is assigned in the first message. This value must be included only
// in the first packet for a given channel. All other packets must be
// identified using channel ID.
optional string channel_name = 2;
optional bytes data = 3;
}
......@@ -55,7 +55,9 @@ bool BufferedSocketWriterBase::Write(
buffer_size_ += data->size();
DoWrite();
return true;
// DoWrite() may trigger OnWriteError() to be called.
return !closed_;
}
void BufferedSocketWriterBase::DoWrite() {
......
// 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_PROTOCOL_CHANNEL_FACTORY_H_
#define REMOTING_PROTOCOL_CHANNEL_FACTORY_H_
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/non_thread_safe.h"
namespace net {
class Socket;
class StreamSocket;
} // namespace net
namespace remoting {
namespace protocol {
class ChannelFactory : public base::NonThreadSafe {
public:
// TODO(sergeyu): Specify connection error code when channel
// connection fails.
typedef base::Callback<void(scoped_ptr<net::StreamSocket>)>
StreamChannelCallback;
typedef base::Callback<void(scoped_ptr<net::Socket>)>
DatagramChannelCallback;
ChannelFactory() {}
// Creates new channels for this connection. The specified callback is called
// when then new channel is created and connected. The callback is called with
// NULL if connection failed for any reason. Callback may be called
// synchronously, before the call returns. All channels must be destroyed
// before the factory is destroyed and CancelChannelCreation() must be called
// to cancel creation of channels for which the |callback| hasn't been called
// yet.
virtual void CreateStreamChannel(
const std::string& name, const StreamChannelCallback& callback) = 0;
virtual void CreateDatagramChannel(
const std::string& name, const DatagramChannelCallback& callback) = 0;
// Cancels a pending CreateStreamChannel() or CreateDatagramChannel()
// operation for the named channel. If the channel creation already
// completed then canceling it has no effect. When shutting down
// this method must be called for each channel pending creation.
virtual void CancelChannelCreation(const std::string& name) = 0;
protected:
virtual ~ChannelFactory() {}
private:
DISALLOW_COPY_AND_ASSIGN(ChannelFactory);
};
} // namespace protocol
} // namespace remoting
#endif // REMOTING_PROTOCOL_CHANNEL_FACTORY_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_PROTOCOL_CHANNEL_MULTIPLEXER_H_
#define REMOTING_PROTOCOL_CHANNEL_MULTIPLEXER_H_
#include "remoting/proto/mux.pb.h"
#include "remoting/protocol/buffered_socket_writer.h"
#include "remoting/protocol/channel_factory.h"
#include "remoting/protocol/message_reader.h"
namespace remoting {
namespace protocol {
class ChannelMultiplexer : public ChannelFactory {
public:
static const char kMuxChannelName[];
// |factory| is used to create the channel upon which to multiplex.
ChannelMultiplexer(ChannelFactory* factory,
const std::string& base_channel_name);
virtual ~ChannelMultiplexer();
// ChannelFactory interface.
virtual void CreateStreamChannel(
const std::string& name,
const StreamChannelCallback& callback) OVERRIDE;
virtual void CreateDatagramChannel(
const std::string& name,
const DatagramChannelCallback& callback) OVERRIDE;
virtual void CancelChannelCreation(const std::string& name) OVERRIDE;
private:
struct PendingChannel;
class MuxChannel;
class MuxSocket;
friend class MuxChannel;
// Callback for |base_channel_| creation.
void OnBaseChannelReady(scoped_ptr<net::StreamSocket> socket);
// Helper method used to create channels.
MuxChannel* GetOrCreateChannel(const std::string& name);
// Callbacks for |writer_| and |reader_|.
void OnWriteFailed(int error);
void OnIncomingPacket(scoped_ptr<MultiplexPacket> packet,
const base::Closure& done_task);
// Called by MuxChannel.
bool DoWrite(scoped_ptr<MultiplexPacket> packet,
const base::Closure& done_task);
// Factory used to create |base_channel_|. Set to NULL once creation is
// finished or failed.
ChannelFactory* base_channel_factory_;
// Name of the underlying channel.
std::string base_channel_name_;
// The channel over which to multiplex.
scoped_ptr<net::StreamSocket> base_channel_;
// List of requested channels while we are waiting for |base_channel_|.
std::list<PendingChannel> pending_channels_;
int next_channel_id_;
std::map<std::string, MuxChannel*> channels_;
// Channels are added to |channels_by_receive_id_| only after we receive
// receive_id from the remote peer.
std::map<int, MuxChannel*> channels_by_receive_id_;
BufferedSocketWriter writer_;
ProtobufMessageReader<MultiplexPacket> reader_;
// Flag used by OnWriteFailed() to detect when the multiplexer is destroyed.
bool* destroyed_flag_;
DISALLOW_COPY_AND_ASSIGN(ChannelMultiplexer);
};
} // namespace protocol
} // namespace remoting
#endif // REMOTING_PROTOCOL_CHANNEL_MULTIPLEXER_H_
This diff is collapsed.
......@@ -34,6 +34,7 @@ class StreamConnectionTester {
~StreamConnectionTester();
void Start();
bool done() { return done_; }
void CheckResults();
protected:
......
......@@ -7,16 +7,12 @@
#include <string>
#include "base/callback.h"
#include "base/threading/non_thread_safe.h"
#include "remoting/protocol/buffered_socket_writer.h"
#include "remoting/protocol/channel_factory.h"
#include "remoting/protocol/errors.h"
#include "remoting/protocol/session_config.h"
namespace net {
class IPEndPoint;
class Socket;
class StreamSocket;
} // namespace net
namespace remoting {
......@@ -27,7 +23,7 @@ struct TransportRoute;
// Generic interface for Chromotocol connection used by both client and host.
// Provides access to the connection channels, but doesn't depend on the
// protocol used for each channel.
class Session : public base::NonThreadSafe {
class Session : public ChannelFactory {
public:
enum State {
// Created, but not connecting yet.
......@@ -74,12 +70,6 @@ class Session : public base::NonThreadSafe {
bool ready) {}
};
// TODO(sergeyu): Specify connection error code when channel
// connection fails.
typedef base::Callback<void(scoped_ptr<net::StreamSocket>)>
StreamChannelCallback;
typedef base::Callback<void(scoped_ptr<net::Socket>)>
DatagramChannelCallback;
Session() {}
virtual ~Session() {}
......@@ -91,23 +81,6 @@ class Session : public base::NonThreadSafe {
// Returns error code for a failed session.
virtual ErrorCode error() = 0;
// Creates new channels for this connection. The specified callback
// is called when then new channel is created and connected. The
// callback is called with NULL if connection failed for any reason.
// All channels must be destroyed before the session is
// destroyed. Can be called only when in CONNECTING, CONNECTED or
// AUTHENTICATED states.
virtual void CreateStreamChannel(
const std::string& name, const StreamChannelCallback& callback) = 0;
virtual void CreateDatagramChannel(
const std::string& name, const DatagramChannelCallback& callback) = 0;
// Cancels a pending CreateStreamChannel() or CreateDatagramChannel()
// operation for the named channel. If the channel creation already
// completed then cancelling it has no effect. When shutting down
// this method must be called for each channel pending creation.
virtual void CancelChannelCreation(const std::string& name) = 0;
// JID of the other side.
virtual const std::string& jid() = 0;
......
......@@ -1616,6 +1616,8 @@
'protocol/channel_authenticator.h',
'protocol/channel_dispatcher_base.cc',
'protocol/channel_dispatcher_base.h',
'protocol/channel_multiplexer.cc',
'protocol/channel_multiplexer.h',
'protocol/client_control_dispatcher.cc',
'protocol/client_control_dispatcher.h',
'protocol/client_event_dispatcher.cc',
......@@ -1623,11 +1625,11 @@
'protocol/client_stub.h',
'protocol/clipboard_echo_filter.cc',
'protocol/clipboard_echo_filter.h',
'protocol/clipboard_filter.h',
'protocol/clipboard_filter.cc',
'protocol/clipboard_filter.h',
'protocol/clipboard_stub.h',
'protocol/clipboard_thread_proxy.cc',
'protocol/clipboard_thread_proxy.h',
'protocol/clipboard_stub.h',
'protocol/connection_to_client.cc',
'protocol/connection_to_client.h',
'protocol/connection_to_host.cc',
......@@ -1802,6 +1804,7 @@
'protocol/authenticator_test_base.cc',
'protocol/authenticator_test_base.h',
'protocol/buffered_socket_writer_unittest.cc',
'protocol/channel_multiplexer_unittest.cc',
'protocol/clipboard_echo_filter_unittest.cc',
'protocol/connection_tester.cc',
'protocol/connection_tester.h',
......
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