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 |