Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/protocol/libjingle_transport_factory.h" | 5 #include "remoting/protocol/libjingle_transport_factory.h" |
| 6 | 6 |
| 7 #include "base/message_loop_proxy.h" | 7 #include "base/message_loop_proxy.h" |
| 8 #include "jingle/glue/channel_socket_adapter.h" | 8 #include "jingle/glue/channel_socket_adapter.h" |
| 9 #include "jingle/glue/pseudotcp_adapter.h" | 9 #include "jingle/glue/pseudotcp_adapter.h" |
| 10 #include "jingle/glue/utils.h" | 10 #include "jingle/glue/utils.h" |
| 11 #include "net/base/net_errors.h" | 11 #include "net/base/net_errors.h" |
| 12 #include "remoting/base/constants.h" | 12 #include "remoting/base/constants.h" |
| 13 #include "remoting/protocol/channel_authenticator.h" | 13 #include "remoting/protocol/channel_authenticator.h" |
| 14 #include "remoting/protocol/transport_config.h" | 14 #include "remoting/protocol/transport_config.h" |
| 15 #include "third_party/libjingle/source/talk/base/basicpacketsocketfactory.h" | 15 #include "third_party/libjingle/source/talk/base/basicpacketsocketfactory.h" |
| 16 #include "third_party/libjingle/source/talk/base/network.h" | 16 #include "third_party/libjingle/source/talk/base/network.h" |
| 17 #include "third_party/libjingle/source/talk/p2p/base/p2ptransportchannel.h" | 17 #include "third_party/libjingle/source/talk/p2p/base/p2ptransportchannel.h" |
| 18 #include "third_party/libjingle/source/talk/p2p/client/httpportallocator.h" | 18 #include "third_party/libjingle/source/talk/p2p/client/basicportallocator.h" |
| 19 | 19 |
| 20 namespace remoting { | 20 namespace remoting { |
| 21 namespace protocol { | 21 namespace protocol { |
| 22 | 22 |
| 23 namespace { | 23 namespace { |
| 24 | 24 |
| 25 // Value is choosen to balance the extra latency against the reduced | 25 // Value is choosen to balance the extra latency against the reduced |
| 26 // load due to ACK traffic. | 26 // load due to ACK traffic. |
| 27 const int kTcpAckDelayMilliseconds = 10; | 27 const int kTcpAckDelayMilliseconds = 10; |
| 28 | 28 |
| 29 // Values for the TCP send and receive buffer size. This should be tuned to | 29 // Values for the TCP send and receive buffer size. This should be tuned to |
| 30 // accomodate high latency network but not backlog the decoding pipeline. | 30 // accomodate high latency network but not backlog the decoding pipeline. |
| 31 const int kTcpReceiveBufferSize = 256 * 1024; | 31 const int kTcpReceiveBufferSize = 256 * 1024; |
| 32 const int kTcpSendBufferSize = kTcpReceiveBufferSize + 30 * 1024; | 32 const int kTcpSendBufferSize = kTcpReceiveBufferSize + 30 * 1024; |
| 33 | 33 |
| 34 class LibjingleStreamTransport : public StreamTransport, | 34 class LibjingleStreamTransport : public StreamTransport, |
| 35 public sigslot::has_slots<> { | 35 public sigslot::has_slots<> { |
| 36 public: | 36 public: |
| 37 LibjingleStreamTransport(talk_base::NetworkManager* network_manager, | 37 LibjingleStreamTransport(cricket::PortAllocator* port_allocator, |
| 38 talk_base::PacketSocketFactory* socket_factory); | 38 bool incoming_only); |
| 39 virtual ~LibjingleStreamTransport(); | 39 virtual ~LibjingleStreamTransport(); |
| 40 | 40 |
| 41 // StreamTransport interface. | 41 // StreamTransport interface. |
| 42 virtual void Initialize( | 42 virtual void Initialize( |
| 43 const std::string& name, | 43 const std::string& name, |
| 44 const TransportConfig& config, | 44 const TransportConfig& config, |
| 45 Transport::EventHandler* event_handler, | 45 Transport::EventHandler* event_handler, |
| 46 scoped_ptr<ChannelAuthenticator> authenticator) OVERRIDE; | 46 scoped_ptr<ChannelAuthenticator> authenticator) OVERRIDE; |
| 47 virtual void Connect( | 47 virtual void Connect( |
| 48 const StreamTransport::ConnectedCallback& callback) OVERRIDE; | 48 const StreamTransport::ConnectedCallback& callback) OVERRIDE; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 59 | 59 |
| 60 void OnTcpConnected(int result); | 60 void OnTcpConnected(int result); |
| 61 void OnAuthenticationDone(net::Error error, | 61 void OnAuthenticationDone(net::Error error, |
| 62 scoped_ptr<net::StreamSocket> socket); | 62 scoped_ptr<net::StreamSocket> socket); |
| 63 | 63 |
| 64 void OnChannelDestroyed(); | 64 void OnChannelDestroyed(); |
| 65 | 65 |
| 66 void NotifyConnected(scoped_ptr<net::StreamSocket> socket); | 66 void NotifyConnected(scoped_ptr<net::StreamSocket> socket); |
| 67 void NotifyConnectFailed(); | 67 void NotifyConnectFailed(); |
| 68 | 68 |
| 69 talk_base::NetworkManager* network_manager_; | 69 cricket::PortAllocator* port_allocator_; |
|
Wez
2012/04/27 17:58:51
So the LibjingleTransportFactory now owns the Port
Sergey Ulanov
2012/04/27 22:51:14
No. Don't think we need it - it would crash it qui
| |
| 70 talk_base::PacketSocketFactory* socket_factory_; | 70 bool incoming_only_; |
| 71 | 71 |
| 72 std::string name_; | 72 std::string name_; |
| 73 TransportConfig config_; | 73 TransportConfig config_; |
| 74 EventHandler* event_handler_; | 74 EventHandler* event_handler_; |
| 75 StreamTransport::ConnectedCallback callback_; | 75 StreamTransport::ConnectedCallback callback_; |
| 76 scoped_ptr<ChannelAuthenticator> authenticator_; | 76 scoped_ptr<ChannelAuthenticator> authenticator_; |
| 77 | 77 |
| 78 scoped_ptr<cricket::PortAllocator> port_allocator_; | |
| 79 cricket::HttpPortAllocator* http_port_allocator_; | |
| 80 scoped_ptr<cricket::P2PTransportChannel> channel_; | 78 scoped_ptr<cricket::P2PTransportChannel> channel_; |
| 81 | 79 |
| 82 // We own |socket_| until it is connected. | 80 // We own |socket_| until it is connected. |
| 83 scoped_ptr<jingle_glue::PseudoTcpAdapter> socket_; | 81 scoped_ptr<jingle_glue::PseudoTcpAdapter> socket_; |
| 84 | 82 |
| 85 DISALLOW_COPY_AND_ASSIGN(LibjingleStreamTransport); | 83 DISALLOW_COPY_AND_ASSIGN(LibjingleStreamTransport); |
| 86 }; | 84 }; |
| 87 | 85 |
| 88 LibjingleStreamTransport::LibjingleStreamTransport( | 86 LibjingleStreamTransport::LibjingleStreamTransport( |
| 89 talk_base::NetworkManager* network_manager, | 87 cricket::PortAllocator* port_allocator, |
| 90 talk_base::PacketSocketFactory* socket_factory) | 88 bool incoming_only) |
| 91 : network_manager_(network_manager), | 89 : port_allocator_(port_allocator), |
| 92 socket_factory_(socket_factory), | 90 incoming_only_(incoming_only), |
| 93 event_handler_(NULL), | 91 event_handler_(NULL) { |
| 94 http_port_allocator_(NULL) { | |
| 95 } | 92 } |
| 96 | 93 |
| 97 LibjingleStreamTransport::~LibjingleStreamTransport() { | 94 LibjingleStreamTransport::~LibjingleStreamTransport() { |
| 98 DCHECK(event_handler_); | 95 DCHECK(event_handler_); |
| 99 event_handler_->OnTransportDeleted(this); | 96 event_handler_->OnTransportDeleted(this); |
| 100 // Channel should be already destroyed if we were connected. | 97 // Channel should be already destroyed if we were connected. |
| 101 DCHECK(!is_connected() || socket_.get() == NULL); | 98 DCHECK(!is_connected() || socket_.get() == NULL); |
| 102 | 99 |
| 103 if (channel_.get()) { | 100 if (channel_.get()) { |
| 104 base::MessageLoopProxy::current()->DeleteSoon( | 101 base::MessageLoopProxy::current()->DeleteSoon( |
| 105 FROM_HERE, channel_.release()); | 102 FROM_HERE, channel_.release()); |
| 106 } | 103 } |
| 107 if (port_allocator_.get()) { | |
| 108 base::MessageLoopProxy::current()->DeleteSoon( | |
| 109 FROM_HERE, port_allocator_.release()); | |
| 110 } | |
| 111 } | 104 } |
| 112 | 105 |
| 113 void LibjingleStreamTransport::Initialize( | 106 void LibjingleStreamTransport::Initialize( |
| 114 const std::string& name, | 107 const std::string& name, |
| 115 const TransportConfig& config, | 108 const TransportConfig& config, |
| 116 Transport::EventHandler* event_handler, | 109 Transport::EventHandler* event_handler, |
| 117 scoped_ptr<ChannelAuthenticator> authenticator) { | 110 scoped_ptr<ChannelAuthenticator> authenticator) { |
| 118 DCHECK(CalledOnValidThread()); | 111 DCHECK(CalledOnValidThread()); |
| 119 | 112 |
| 120 DCHECK(!name.empty()); | 113 DCHECK(!name.empty()); |
| 121 DCHECK(event_handler); | 114 DCHECK(event_handler); |
| 122 | 115 |
| 123 // Can be initialized only once. | 116 // Can be initialized only once. |
| 124 DCHECK(name_.empty()); | 117 DCHECK(name_.empty()); |
| 125 | 118 |
| 126 name_ = name; | 119 name_ = name; |
| 127 config_ = config; | 120 config_ = config; |
| 128 event_handler_ = event_handler; | 121 event_handler_ = event_handler; |
| 129 authenticator_ = authenticator.Pass(); | 122 authenticator_ = authenticator.Pass(); |
| 130 } | 123 } |
| 131 | 124 |
| 132 void LibjingleStreamTransport::Connect( | 125 void LibjingleStreamTransport::Connect( |
| 133 const StreamTransport::ConnectedCallback& callback) { | 126 const StreamTransport::ConnectedCallback& callback) { |
| 134 DCHECK(CalledOnValidThread()); | 127 DCHECK(CalledOnValidThread()); |
| 135 | 128 |
| 136 callback_ = callback; | 129 callback_ = callback; |
| 137 | 130 |
| 138 // Create port allocator first. | |
| 139 | |
| 140 // We always use PseudoTcp to provide a reliable channel. However | |
| 141 // when it is used together with TCP the performance is very bad | |
| 142 // so we explicitly disable TCP connections. | |
| 143 int port_allocator_flags = cricket::PORTALLOCATOR_DISABLE_TCP; | |
| 144 if (config_.nat_traversal_mode == TransportConfig::NAT_TRAVERSAL_ENABLED) { | |
| 145 http_port_allocator_ = new cricket::HttpPortAllocator( | |
| 146 network_manager_, socket_factory_, ""); | |
| 147 port_allocator_.reset(http_port_allocator_); | |
| 148 } else { | |
| 149 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_STUN | | |
| 150 cricket::PORTALLOCATOR_DISABLE_RELAY; | |
| 151 port_allocator_.reset( | |
| 152 new cricket::BasicPortAllocator(network_manager_, socket_factory_)); | |
| 153 } | |
| 154 port_allocator_->set_flags(port_allocator_flags); | |
| 155 | |
| 156 port_allocator_->SetPortRange(config_.min_port, config_.max_port); | |
| 157 | |
| 158 DCHECK(!channel_.get()); | 131 DCHECK(!channel_.get()); |
| 159 | 132 |
| 160 // Create P2PTransportChannel, attach signal handlers and connect it. | 133 // Create P2PTransportChannel, attach signal handlers and connect it. |
| 161 // TODO(sergeyu): Specify correct component ID for the channel. | 134 // TODO(sergeyu): Specify correct component ID for the channel. |
| 162 channel_.reset(new cricket::P2PTransportChannel( | 135 channel_.reset(new cricket::P2PTransportChannel( |
| 163 name_, 0, NULL, port_allocator_.get())); | 136 name_, 0, NULL, port_allocator_)); |
| 164 channel_->SignalRequestSignaling.connect( | 137 channel_->SignalRequestSignaling.connect( |
| 165 this, &LibjingleStreamTransport::OnRequestSignaling); | 138 this, &LibjingleStreamTransport::OnRequestSignaling); |
| 166 channel_->SignalCandidateReady.connect( | 139 channel_->SignalCandidateReady.connect( |
| 167 this, &LibjingleStreamTransport::OnCandidateReady); | 140 this, &LibjingleStreamTransport::OnCandidateReady); |
| 168 channel_->SignalRouteChange.connect( | 141 channel_->SignalRouteChange.connect( |
| 169 this, &LibjingleStreamTransport::OnRouteChange); | 142 this, &LibjingleStreamTransport::OnRouteChange); |
| 170 if (config_.nat_traversal_mode == TransportConfig::NAT_TRAVERSAL_DISABLED) | 143 channel_->set_incoming_only(incoming_only_); |
| 171 channel_->set_incoming_only(true); | |
| 172 | 144 |
| 173 channel_->Connect(); | 145 channel_->Connect(); |
| 174 | 146 |
| 175 // Create net::Socket adapter for the P2PTransportChannel. | 147 // Create net::Socket adapter for the P2PTransportChannel. |
| 176 scoped_ptr<jingle_glue::TransportChannelSocketAdapter> channel_adapter( | 148 scoped_ptr<jingle_glue::TransportChannelSocketAdapter> channel_adapter( |
| 177 new jingle_glue::TransportChannelSocketAdapter(channel_.get())); | 149 new jingle_glue::TransportChannelSocketAdapter(channel_.get())); |
| 178 | 150 |
| 179 channel_adapter->SetOnDestroyedCallback(base::Bind( | 151 channel_adapter->SetOnDestroyedCallback(base::Bind( |
| 180 &LibjingleStreamTransport::OnChannelDestroyed, base::Unretained(this))); | 152 &LibjingleStreamTransport::OnChannelDestroyed, base::Unretained(this))); |
| 181 | 153 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 304 DCHECK(!is_connected()); | 276 DCHECK(!is_connected()); |
| 305 | 277 |
| 306 socket_.reset(); | 278 socket_.reset(); |
| 307 | 279 |
| 308 // This method may be called in response to a libjingle signal, so | 280 // This method may be called in response to a libjingle signal, so |
| 309 // libjingle objects must be deleted asynchronously. | 281 // libjingle objects must be deleted asynchronously. |
| 310 if (channel_.get()) { | 282 if (channel_.get()) { |
| 311 base::MessageLoopProxy::current()->DeleteSoon( | 283 base::MessageLoopProxy::current()->DeleteSoon( |
| 312 FROM_HERE, channel_.release()); | 284 FROM_HERE, channel_.release()); |
| 313 } | 285 } |
| 314 if (port_allocator_.get()) { | |
| 315 base::MessageLoopProxy::current()->DeleteSoon( | |
| 316 FROM_HERE, port_allocator_.release()); | |
| 317 } | |
| 318 | 286 |
| 319 authenticator_.reset(); | 287 authenticator_.reset(); |
| 320 | 288 |
| 321 NotifyConnected(scoped_ptr<net::StreamSocket>(NULL)); | 289 NotifyConnected(scoped_ptr<net::StreamSocket>(NULL)); |
| 322 } | 290 } |
| 323 | 291 |
| 324 } // namespace | 292 } // namespace |
| 325 | 293 |
| 294 LibjingleTransportFactory::LibjingleTransportFactory( | |
| 295 scoped_ptr<talk_base::NetworkManager> network_manager, | |
| 296 scoped_ptr<talk_base::PacketSocketFactory> socket_factory, | |
| 297 scoped_ptr<cricket::PortAllocator> port_allocator, | |
| 298 bool incoming_only) | |
| 299 : network_manager_(network_manager.Pass()), | |
| 300 socket_factory_(socket_factory.Pass()), | |
| 301 port_allocator_(port_allocator.Pass()), | |
| 302 incoming_only_(incoming_only) { | |
| 303 } | |
| 304 | |
| 326 LibjingleTransportFactory::LibjingleTransportFactory() | 305 LibjingleTransportFactory::LibjingleTransportFactory() |
| 327 : network_manager_(new talk_base::BasicNetworkManager()), | 306 : network_manager_(new talk_base::BasicNetworkManager()), |
| 328 socket_factory_(new talk_base::BasicPacketSocketFactory( | 307 socket_factory_(new talk_base::BasicPacketSocketFactory()), |
| 329 talk_base::Thread::Current())) { | 308 port_allocator_(new cricket::BasicPortAllocator( |
| 309 network_manager_.get(), socket_factory_.get())) { | |
| 330 } | 310 } |
| 331 | 311 |
| 332 LibjingleTransportFactory::~LibjingleTransportFactory() { | 312 LibjingleTransportFactory::~LibjingleTransportFactory() { |
| 333 // This method may be called in response to a libjingle signal, so | 313 // This method may be called in response to a libjingle signal, so |
| 334 // libjingle objects must be deleted asynchronously. | 314 // libjingle objects must be deleted asynchronously. |
| 335 base::MessageLoopProxy::current()->DeleteSoon( | 315 base::MessageLoopProxy::current()->DeleteSoon( |
| 316 FROM_HERE, port_allocator_.release()); | |
| 317 base::MessageLoopProxy::current()->DeleteSoon( | |
| 336 FROM_HERE, socket_factory_.release()); | 318 FROM_HERE, socket_factory_.release()); |
| 337 base::MessageLoopProxy::current()->DeleteSoon( | 319 base::MessageLoopProxy::current()->DeleteSoon( |
| 338 FROM_HERE, network_manager_.release()); | 320 FROM_HERE, network_manager_.release()); |
| 339 } | 321 } |
| 340 | 322 |
| 341 scoped_ptr<StreamTransport> LibjingleTransportFactory::CreateStreamTransport() { | 323 scoped_ptr<StreamTransport> LibjingleTransportFactory::CreateStreamTransport() { |
| 342 return scoped_ptr<StreamTransport>( | 324 return scoped_ptr<StreamTransport>( |
| 343 new LibjingleStreamTransport(network_manager_.get(), | 325 new LibjingleStreamTransport(port_allocator_.get(), incoming_only_)); |
| 344 socket_factory_.get())); | |
| 345 } | 326 } |
| 346 | 327 |
| 347 scoped_ptr<DatagramTransport> | 328 scoped_ptr<DatagramTransport> |
| 348 LibjingleTransportFactory::CreateDatagramTransport() { | 329 LibjingleTransportFactory::CreateDatagramTransport() { |
| 349 NOTIMPLEMENTED(); | 330 NOTIMPLEMENTED(); |
| 350 return scoped_ptr<DatagramTransport>(NULL); | 331 return scoped_ptr<DatagramTransport>(NULL); |
| 351 } | 332 } |
| 352 | 333 |
| 353 } // namespace protocol | 334 } // namespace protocol |
| 354 } // namespace remoting | 335 } // namespace remoting |
| OLD | NEW |