Commit 28d886c9 authored by sergeyu's avatar sergeyu Committed by Commit bot

Move PseudoTCP and channel auth out of LibjingleTransportFactory.

Previously TransportFactory interface was responsible for creation
and initialization of several protocol layers, including PseudoTCP and
authentication (TLS). Simplified it so now it only creates raw datagram
transport channel. PseudoTcpChannelFactory is now responsible for
setting up PseudoTcpAdapter and AuthenticatingChannelFactory takes care
of channel authentication. Also added DatagramChannelFactory for
Datagram channels.

This change will make it possible to replace PseudoTcpChannelFactory
with an object that creates SCTP-based channels.

Also fixed a bug in SslHmacChannelAuthenticator. It wasn't working
properly when deleted from the callback. (base::Callback objects
shouldn't be deleted while being called because when deleted they
also destroy reference parameters values they are holding).

BUG=402993

Review URL: https://codereview.chromium.org/551173004

Cr-Commit-Position: refs/heads/master@{#294474}
parent 042e7e07
......@@ -44,6 +44,7 @@ static_library("protocol") {
"connection_to_host.h",
"content_description.cc",
"content_description.h",
"datagram_channel_factory.h",
"errors.h",
"host_control_dispatcher.cc",
"host_control_dispatcher.h",
......@@ -98,6 +99,10 @@ static_library("protocol") {
"protobuf_video_reader.h",
"protobuf_video_writer.cc",
"protobuf_video_writer.h",
"pseudotcp_channel_factory.cc",
"pseudotcp_channel_factory.h",
"secure_channel_factory.cc",
"secure_channel_factory.h",
"session.h",
"session_config.cc",
"session_config.h",
......@@ -106,6 +111,7 @@ static_library("protocol") {
"socket_util.h",
"ssl_hmac_channel_authenticator.cc",
"ssl_hmac_channel_authenticator.h",
"stream_channel_factory.h",
"third_party_authenticator_base.cc",
"third_party_authenticator_base.h",
"third_party_client_authenticator.cc",
......
......@@ -10,6 +10,7 @@
#include "base/path_service.h"
#include "base/test/test_timeouts.h"
#include "base/timer/timer.h"
#include "net/base/net_errors.h"
#include "net/base/test_data_directory.h"
#include "remoting/base/rsa_key_pair.h"
#include "remoting/protocol/authenticator.h"
......@@ -157,14 +158,14 @@ void AuthenticatorTestBase::RunChannelAuth(bool expected_fail) {
}
void AuthenticatorTestBase::OnHostConnected(
net::Error error,
int error,
scoped_ptr<net::StreamSocket> socket) {
host_callback_.OnDone(error);
host_socket_ = socket.Pass();
}
void AuthenticatorTestBase::OnClientConnected(
net::Error error,
int error,
scoped_ptr<net::StreamSocket> socket) {
client_callback_.OnDone(error);
client_socket_ = socket.Pass();
......
......@@ -9,7 +9,6 @@
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "net/base/net_errors.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -37,7 +36,7 @@ class AuthenticatorTestBase : public testing::Test {
public:
MockChannelDoneCallback();
~MockChannelDoneCallback();
MOCK_METHOD1(OnDone, void(net::Error error));
MOCK_METHOD1(OnDone, void(int error));
};
static void ContinueAuthExchangeWith(Authenticator* sender,
......@@ -49,9 +48,9 @@ class AuthenticatorTestBase : public testing::Test {
void RunHostInitiatedAuthExchange();
void RunChannelAuth(bool expected_fail);
void OnHostConnected(net::Error error,
void OnHostConnected(int error,
scoped_ptr<net::StreamSocket> socket);
void OnClientConnected(net::Error error,
void OnClientConnected(int error,
scoped_ptr<net::StreamSocket> socket);
base::MessageLoop message_loop_;
......
......@@ -8,7 +8,6 @@
#include <string>
#include "base/callback_forward.h"
#include "net/base/net_errors.h"
namespace net {
class StreamSocket;
......@@ -23,14 +22,14 @@ namespace protocol {
// should be used only once for one channel.
class ChannelAuthenticator {
public:
typedef base::Callback<void(net::Error error, scoped_ptr<net::StreamSocket>)>
typedef base::Callback<void(int error, scoped_ptr<net::StreamSocket>)>
DoneCallback;
virtual ~ChannelAuthenticator() {}
// Start authentication of the given |socket|. |done_callback| is
// called when authentication is finished. Callback may be invoked
// before this method returns.
// Start authentication of the given |socket|. |done_callback| is called when
// authentication is finished. Callback may be invoked before this method
// returns, and may delete the calling authenticator.
virtual void SecureAndAuthenticate(
scoped_ptr<net::StreamSocket> socket,
const DoneCallback& done_callback) = 0;
......
......@@ -6,9 +6,9 @@
#include "base/bind.h"
#include "net/socket/stream_socket.h"
#include "remoting/protocol/channel_factory.h"
#include "remoting/protocol/session.h"
#include "remoting/protocol/session_config.h"
#include "remoting/protocol/stream_channel_factory.h"
namespace remoting {
namespace protocol {
......
......@@ -19,7 +19,7 @@ namespace remoting {
namespace protocol {
struct ChannelConfig;
class ChannelFactory;
class StreamChannelFactory;
class Session;
// Base class for channel message dispatchers. It's responsible for
......@@ -56,7 +56,7 @@ class ChannelDispatcherBase {
void OnChannelReady(scoped_ptr<net::StreamSocket> socket);
std::string channel_name_;
ChannelFactory* channel_factory_;
StreamChannelFactory* channel_factory_;
InitializedCallback initialized_callback_;
scoped_ptr<net::StreamSocket> channel_;
......
......@@ -353,7 +353,7 @@ void ChannelMultiplexer::MuxSocket::OnPacketReceived() {
}
}
ChannelMultiplexer::ChannelMultiplexer(ChannelFactory* factory,
ChannelMultiplexer::ChannelMultiplexer(StreamChannelFactory* factory,
const std::string& base_channel_name)
: base_channel_factory_(factory),
base_channel_name_(base_channel_name),
......
......@@ -8,22 +8,22 @@
#include "base/memory/weak_ptr.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"
#include "remoting/protocol/stream_channel_factory.h"
namespace remoting {
namespace protocol {
class ChannelMultiplexer : public ChannelFactory {
class ChannelMultiplexer : public StreamChannelFactory {
public:
static const char kMuxChannelName[];
// |factory| is used to create the channel upon which to multiplex.
ChannelMultiplexer(ChannelFactory* factory,
ChannelMultiplexer(StreamChannelFactory* factory,
const std::string& base_channel_name);
virtual ~ChannelMultiplexer();
// ChannelFactory interface.
// StreamChannelFactory interface.
virtual void CreateChannel(const std::string& name,
const ChannelCreatedCallback& callback) OVERRIDE;
virtual void CancelChannelCreation(const std::string& name) OVERRIDE;
......@@ -59,7 +59,7 @@ class ChannelMultiplexer : public ChannelFactory {
// Factory used to create |base_channel_|. Set to NULL once creation is
// finished or failed.
ChannelFactory* base_channel_factory_;
StreamChannelFactory* base_channel_factory_;
// Name of the underlying channel.
std::string base_channel_name_;
......
// Copyright 2014 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_DATAGRAM_CHANNEL_FACTORY_H_
#define REMOTING_PROTOCOL_DATAGRAM_CHANNEL_FACTORY_H_
namespace net {
class Socket;
} // namespace net
namespace remoting {
namespace protocol {
class DatagramChannelFactory {
public:
typedef base::Callback<void(scoped_ptr<net::Socket>)>
ChannelCreatedCallback;
DatagramChannelFactory() {}
// Creates new channels and calls the |callback| when then new channel is
// created and connected. The |callback| is called with NULL if channel setup
// failed for any reason. Callback may be called synchronously, before the
// call returns. All channels must be destroyed, and CancelChannelCreation()
// called for any pending channels, before the factory is destroyed.
virtual void CreateChannel(const std::string& name,
const ChannelCreatedCallback& callback) = 0;
// Cancels a pending CreateChannel() 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 ~DatagramChannelFactory() {}
private:
DISALLOW_COPY_AND_ASSIGN(DatagramChannelFactory);
};
} // namespace protocol
} // namespace remoting
#endif // REMOTING_PROTOCOL_DATAGRAM_CHANNEL_FACTORY_H_
......@@ -7,6 +7,7 @@
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/socket/stream_socket.h"
#include "remoting/base/constants.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -34,31 +35,33 @@ void FakeChannelAuthenticator::SecureAndAuthenticate(
if (async_) {
done_callback_ = done_callback;
scoped_refptr<net::IOBuffer> write_buf = new net::IOBuffer(1);
write_buf->data()[0] = 0;
int result =
socket_->Write(write_buf.get(),
1,
base::Bind(&FakeChannelAuthenticator::OnAuthBytesWritten,
weak_factory_.GetWeakPtr()));
if (result != net::ERR_IO_PENDING) {
// This will not call the callback because |did_read_bytes_| is
// still set to false.
OnAuthBytesWritten(result);
if (result_ != net::OK) {
// Don't write anything if we are going to reject auth to make test
// ordering deterministic.
did_write_bytes_ = true;
} else {
scoped_refptr<net::IOBuffer> write_buf = new net::IOBuffer(1);
write_buf->data()[0] = 0;
int result = socket_->Write(
write_buf.get(), 1,
base::Bind(&FakeChannelAuthenticator::OnAuthBytesWritten,
weak_factory_.GetWeakPtr()));
if (result != net::ERR_IO_PENDING) {
// This will not call the callback because |did_read_bytes_| is
// still set to false.
OnAuthBytesWritten(result);
}
}
scoped_refptr<net::IOBuffer> read_buf = new net::IOBuffer(1);
result =
socket_->Read(read_buf.get(),
1,
int result =
socket_->Read(read_buf.get(), 1,
base::Bind(&FakeChannelAuthenticator::OnAuthBytesRead,
weak_factory_.GetWeakPtr()));
if (result != net::ERR_IO_PENDING)
OnAuthBytesRead(result);
} else {
if (result_ != net::OK)
socket_.reset();
done_callback.Run(result_, socket_.Pass());
CallDoneCallback();
}
}
......@@ -67,7 +70,7 @@ void FakeChannelAuthenticator::OnAuthBytesWritten(int result) {
EXPECT_FALSE(did_write_bytes_);
did_write_bytes_ = true;
if (did_read_bytes_)
done_callback_.Run(result_, socket_.Pass());
CallDoneCallback();
}
void FakeChannelAuthenticator::OnAuthBytesRead(int result) {
......@@ -75,7 +78,15 @@ void FakeChannelAuthenticator::OnAuthBytesRead(int result) {
EXPECT_FALSE(did_read_bytes_);
did_read_bytes_ = true;
if (did_write_bytes_)
done_callback_.Run(result_, socket_.Pass());
CallDoneCallback();
}
void FakeChannelAuthenticator::CallDoneCallback() {
DoneCallback callback = done_callback_;
done_callback_.Reset();
if (result_ != net::OK)
socket_.reset();
callback.Run(result_, socket_.Pass());
}
FakeAuthenticator::FakeAuthenticator(
......
......@@ -24,14 +24,12 @@ class FakeChannelAuthenticator : public ChannelAuthenticator {
const DoneCallback& done_callback) OVERRIDE;
private:
void CallCallback(
net::Error error,
scoped_ptr<net::StreamSocket> socket);
void OnAuthBytesWritten(int result);
void OnAuthBytesRead(int result);
net::Error result_;
void CallDoneCallback();
int result_;
bool async_;
scoped_ptr<net::StreamSocket> socket_;
......
......@@ -320,11 +320,11 @@ void FakeSession::set_config(const SessionConfig& config) {
config_ = config;
}
ChannelFactory* FakeSession::GetTransportChannelFactory() {
StreamChannelFactory* FakeSession::GetTransportChannelFactory() {
return this;
}
ChannelFactory* FakeSession::GetMultiplexedChannelFactory() {
StreamChannelFactory* FakeSession::GetMultiplexedChannelFactory() {
return this;
}
......
......@@ -14,8 +14,8 @@
#include "net/base/completion_callback.h"
#include "net/socket/socket.h"
#include "net/socket/stream_socket.h"
#include "remoting/protocol/channel_factory.h"
#include "remoting/protocol/session.h"
#include "remoting/protocol/stream_channel_factory.h"
namespace base {
class MessageLoop;
......@@ -148,7 +148,7 @@ class FakeUdpSocket : public net::Socket {
// FakeSession is a dummy protocol::Session that uses FakeSocket for all
// channels.
class FakeSession : public Session,
public ChannelFactory {
public StreamChannelFactory {
public:
FakeSession();
virtual ~FakeSession();
......@@ -173,11 +173,11 @@ class FakeSession : public Session,
virtual const CandidateSessionConfig* candidate_config() OVERRIDE;
virtual const SessionConfig& config() OVERRIDE;
virtual void set_config(const SessionConfig& config) OVERRIDE;
virtual ChannelFactory* GetTransportChannelFactory() OVERRIDE;
virtual ChannelFactory* GetMultiplexedChannelFactory() OVERRIDE;
virtual StreamChannelFactory* GetTransportChannelFactory() OVERRIDE;
virtual StreamChannelFactory* GetMultiplexedChannelFactory() OVERRIDE;
virtual void Close() OVERRIDE;
// ChannelFactory interface.
// StreamChannelFactory interface.
virtual void CreateChannel(const std::string& name,
const ChannelCreatedCallback& callback) OVERRIDE;
virtual void CancelChannelCreation(const std::string& name) OVERRIDE;
......
......@@ -18,7 +18,10 @@
#include "remoting/protocol/content_description.h"
#include "remoting/protocol/jingle_messages.h"
#include "remoting/protocol/jingle_session_manager.h"
#include "remoting/protocol/pseudotcp_channel_factory.h"
#include "remoting/protocol/secure_channel_factory.h"
#include "remoting/protocol/session_config.h"
#include "remoting/protocol/stream_channel_factory.h"
#include "remoting/signaling/iq_sender.h"
#include "third_party/libjingle/source/talk/p2p/base/candidate.h"
#include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
......@@ -81,7 +84,7 @@ JingleSession::~JingleSession() {
pending_requests_.end());
STLDeleteContainerPointers(transport_info_requests_.begin(),
transport_info_requests_.end());
STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end());
DCHECK(channels_.empty());
session_manager_->SessionDestroyed(this);
}
......@@ -187,7 +190,7 @@ void JingleSession::ContinueAcceptIncomingConnection() {
SetState(CONNECTED);
if (authenticator_->state() == Authenticator::ACCEPTED) {
SetState(AUTHENTICATED);
OnAuthenticated();
} else {
DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE);
if (authenticator_->started()) {
......@@ -218,15 +221,17 @@ void JingleSession::set_config(const SessionConfig& config) {
config_is_set_ = true;
}
ChannelFactory* JingleSession::GetTransportChannelFactory() {
StreamChannelFactory* JingleSession::GetTransportChannelFactory() {
DCHECK(CalledOnValidThread());
return this;
return secure_channel_factory_.get();
}
ChannelFactory* JingleSession::GetMultiplexedChannelFactory() {
StreamChannelFactory* JingleSession::GetMultiplexedChannelFactory() {
DCHECK(CalledOnValidThread());
if (!channel_multiplexer_.get())
channel_multiplexer_.reset(new ChannelMultiplexer(this, kMuxChannelName));
if (!channel_multiplexer_.get()) {
channel_multiplexer_.reset(
new ChannelMultiplexer(GetTransportChannelFactory(), kMuxChannelName));
}
return channel_multiplexer_.get();
}
......@@ -254,19 +259,17 @@ void JingleSession::CreateChannel(const std::string& name,
const ChannelCreatedCallback& callback) {
DCHECK(!channels_[name]);
scoped_ptr<ChannelAuthenticator> channel_authenticator =
authenticator_->CreateChannelAuthenticator();
scoped_ptr<StreamTransport> channel =
session_manager_->transport_factory_->CreateStreamTransport();
channel->Initialize(name, this, channel_authenticator.Pass());
channel->Connect(callback);
scoped_ptr<Transport> channel =
session_manager_->transport_factory_->CreateTransport();
channel->Connect(name, this, callback);
AddPendingRemoteCandidates(channel.get(), name);
channels_[name] = channel.release();
}
void JingleSession::CancelChannelCreation(const std::string& name) {
ChannelsMap::iterator it = channels_.find(name);
if (it != channels_.end() && !it->second->is_connected()) {
if (it != channels_.end()) {
DCHECK(!it->second->is_connected());
delete it->second;
DCHECK(!channels_[name]);
}
......@@ -598,13 +601,22 @@ void JingleSession::ProcessAuthenticationStep() {
void JingleSession::ContinueAuthenticationStep() {
if (authenticator_->state() == Authenticator::ACCEPTED) {
SetState(AUTHENTICATED);
OnAuthenticated();
} else if (authenticator_->state() == Authenticator::REJECTED) {
CloseInternal(AuthRejectionReasonToErrorCode(
authenticator_->rejection_reason()));
}
}
void JingleSession::OnAuthenticated() {
pseudotcp_channel_factory_.reset(new PseudoTcpChannelFactory(this));
secure_channel_factory_.reset(
new SecureChannelFactory(pseudotcp_channel_factory_.get(),
authenticator_.get()));
SetState(AUTHENTICATED);
}
void JingleSession::CloseInternal(ErrorCode error) {
DCHECK(CalledOnValidThread());
......
......@@ -15,7 +15,7 @@
#include "crypto/rsa_private_key.h"
#include "net/base/completion_callback.h"
#include "remoting/protocol/authenticator.h"
#include "remoting/protocol/channel_factory.h"
#include "remoting/protocol/datagram_channel_factory.h"
#include "remoting/protocol/jingle_messages.h"
#include "remoting/protocol/session.h"
#include "remoting/protocol/session_config.h"
......@@ -30,14 +30,17 @@ class StreamSocket;
namespace remoting {
namespace protocol {
class SecureChannelFactory;
class ChannelMultiplexer;
class JingleSessionManager;
class PseudoTcpChannelFactory;
// JingleSessionManager and JingleSession implement the subset of the
// Jingle protocol used in Chromoting. Instances of this class are
// created by the JingleSessionManager.
class JingleSession : public Session,
public ChannelFactory,
class JingleSession : public base::NonThreadSafe,
public Session,
public DatagramChannelFactory,
public Transport::EventHandler {
public:
virtual ~JingleSession();
......@@ -49,11 +52,11 @@ class JingleSession : public Session,
virtual const CandidateSessionConfig* candidate_config() OVERRIDE;
virtual const SessionConfig& config() OVERRIDE;
virtual void set_config(const SessionConfig& config) OVERRIDE;
virtual ChannelFactory* GetTransportChannelFactory() OVERRIDE;
virtual ChannelFactory* GetMultiplexedChannelFactory() OVERRIDE;
virtual StreamChannelFactory* GetTransportChannelFactory() OVERRIDE;
virtual StreamChannelFactory* GetMultiplexedChannelFactory() OVERRIDE;
virtual void Close() OVERRIDE;
// ChannelFactory interface.
// DatagramChannelFactory interface.
virtual void CreateChannel(const std::string& name,
const ChannelCreatedCallback& callback) OVERRIDE;
virtual void CancelChannelCreation(const std::string& name) OVERRIDE;
......@@ -133,6 +136,9 @@ class JingleSession : public Session,
// Called after the authenticating step is finished.
void ContinueAuthenticationStep();
// Called when authentication is finished.
void OnAuthenticated();
// Terminates the session and sends session-terminate if it is
// necessary. |error| specifies the error code in case when the
// session is being closed due to an error.
......@@ -165,6 +171,8 @@ class JingleSession : public Session,
std::list<IqRequest*> transport_info_requests_;
ChannelsMap channels_;
scoped_ptr<PseudoTcpChannelFactory> pseudotcp_channel_factory_;
scoped_ptr<SecureChannelFactory> secure_channel_factory_;
scoped_ptr<ChannelMultiplexer> channel_multiplexer_;
base::OneShotTimer<JingleSession> transport_infos_timer_;
......
......@@ -22,6 +22,7 @@
#include "remoting/protocol/jingle_session_manager.h"
#include "remoting/protocol/libjingle_transport_factory.h"
#include "remoting/protocol/network_settings.h"
#include "remoting/protocol/stream_channel_factory.h"
#include "remoting/signaling/fake_signal_strategy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -139,7 +140,7 @@ class JingleSessionTest : public testing::Test {
}
void CreateSessionManagers(int auth_round_trips, int messages_till_start,
FakeAuthenticator::Action auth_action) {
FakeAuthenticator::Action auth_action) {
host_signal_strategy_.reset(new FakeSignalStrategy(kHostJid));
client_signal_strategy_.reset(new FakeSignalStrategy(kClientJid));
FakeSignalStrategy::Connect(host_signal_strategy_.get(),
......@@ -510,12 +511,13 @@ TEST_F(JingleSessionTest, TestFailedChannelAuth) {
// from the host.
EXPECT_CALL(host_channel_callback_, OnDone(NULL))
.WillOnce(QuitThread());
EXPECT_CALL(client_channel_callback_, OnDone(_))
.Times(AtMost(1));
ExpectRouteChange(kChannelName);
message_loop_->Run();
client_session_->GetTransportChannelFactory()->CancelChannelCreation(
kChannelName);
EXPECT_TRUE(!host_socket_.get());
}
......
......@@ -47,8 +47,7 @@ class LibjingleTransportFactory : public TransportFactory {
// TransportFactory interface.
virtual void PrepareTokens() OVERRIDE;
virtual scoped_ptr<StreamTransport> CreateStreamTransport() OVERRIDE;
virtual scoped_ptr<DatagramTransport> CreateDatagramTransport() OVERRIDE;
virtual scoped_ptr<Transport> CreateTransport() OVERRIDE;
private:
void EnsureFreshJingleInfo();
......
......@@ -8,8 +8,8 @@
#include "net/socket/stream_socket.h"
#include "remoting/base/constants.h"
#include "remoting/proto/video.pb.h"
#include "remoting/protocol/channel_factory.h"
#include "remoting/protocol/session.h"
#include "remoting/protocol/stream_channel_factory.h"
namespace remoting {
namespace protocol {
......
......@@ -17,7 +17,7 @@ class StreamSocket;
namespace remoting {
namespace protocol {
class ChannelFactory;
class StreamChannelFactory;
class Session;
class ProtobufVideoReader : public VideoReader {
......@@ -40,7 +40,7 @@ class ProtobufVideoReader : public VideoReader {
VideoPacketFormat::Encoding encoding_;
ChannelFactory* channel_factory_;
StreamChannelFactory* channel_factory_;
scoped_ptr<net::StreamSocket> channel_;
ProtobufMessageReader<VideoPacket> reader_;
......
......@@ -8,9 +8,9 @@
#include "net/socket/stream_socket.h"
#include "remoting/base/constants.h"
#include "remoting/proto/video.pb.h"
#include "remoting/protocol/channel_factory.h"
#include "remoting/protocol/message_serialization.h"
#include "remoting/protocol/session.h"
#include "remoting/protocol/stream_channel_factory.h"
namespace remoting {
namespace protocol {
......
......@@ -20,7 +20,7 @@ class StreamSocket;
namespace remoting {
namespace protocol {
class ChannelFactory;
class StreamChannelFactory;
class Session;
class ProtobufVideoWriter : public VideoWriter {
......@@ -43,7 +43,7 @@ class ProtobufVideoWriter : public VideoWriter {
InitializedCallback initialized_callback_;
ChannelFactory* channel_factory_;
StreamChannelFactory* channel_factory_;