• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "remoting/protocol/pseudotcp_channel_factory.h"
6 
7 #include "base/bind.h"
8 #include "jingle/glue/pseudotcp_adapter.h"
9 #include "net/base/net_errors.h"
10 #include "net/socket/stream_socket.h"
11 #include "remoting/base/constants.h"
12 #include "remoting/protocol/datagram_channel_factory.h"
13 
14 namespace remoting {
15 namespace protocol {
16 
17 namespace {
18 
19 // Value is chosen to balance the extra latency against the reduced
20 // load due to ACK traffic.
21 const int kTcpAckDelayMilliseconds = 10;
22 
23 // Values for the TCP send and receive buffer size. This should be tuned to
24 // accommodate high latency network but not backlog the decoding pipeline.
25 const int kTcpReceiveBufferSize = 256 * 1024;
26 const int kTcpSendBufferSize = kTcpReceiveBufferSize + 30 * 1024;
27 
28 }  // namespace
29 
PseudoTcpChannelFactory(DatagramChannelFactory * datagram_channel_factory)30 PseudoTcpChannelFactory::PseudoTcpChannelFactory(
31     DatagramChannelFactory* datagram_channel_factory)
32     : datagram_channel_factory_(datagram_channel_factory) {
33 }
34 
~PseudoTcpChannelFactory()35 PseudoTcpChannelFactory::~PseudoTcpChannelFactory() {
36   // CancelChannelCreation() is expected to be called before destruction.
37   DCHECK(pending_sockets_.empty());
38 }
39 
CreateChannel(const std::string & name,const ChannelCreatedCallback & callback)40 void PseudoTcpChannelFactory::CreateChannel(
41     const std::string& name,
42     const ChannelCreatedCallback& callback) {
43   datagram_channel_factory_->CreateChannel(
44       name,
45       base::Bind(&PseudoTcpChannelFactory::OnDatagramChannelCreated,
46                  base::Unretained(this), name, callback));
47 }
48 
CancelChannelCreation(const std::string & name)49 void PseudoTcpChannelFactory::CancelChannelCreation(const std::string& name) {
50   PendingSocketsMap::iterator it = pending_sockets_.find(name);
51   if (it == pending_sockets_.end()) {
52     datagram_channel_factory_->CancelChannelCreation(name);
53   } else {
54     delete it->second;
55     pending_sockets_.erase(it);
56   }
57 }
58 
OnDatagramChannelCreated(const std::string & name,const ChannelCreatedCallback & callback,scoped_ptr<net::Socket> datagram_socket)59 void PseudoTcpChannelFactory::OnDatagramChannelCreated(
60     const std::string& name,
61     const ChannelCreatedCallback& callback,
62     scoped_ptr<net::Socket> datagram_socket) {
63   jingle_glue::PseudoTcpAdapter* adapter =
64       new jingle_glue::PseudoTcpAdapter(datagram_socket.release());
65   pending_sockets_[name] = adapter;
66 
67   adapter->SetSendBufferSize(kTcpSendBufferSize);
68   adapter->SetReceiveBufferSize(kTcpReceiveBufferSize);
69   adapter->SetNoDelay(true);
70   adapter->SetAckDelay(kTcpAckDelayMilliseconds);
71 
72   // TODO(sergeyu): This is a hack to improve latency of the video channel.
73   // Consider removing it once we have better flow control implemented.
74   if (name == kVideoChannelName)
75     adapter->SetWriteWaitsForSend(true);
76 
77   int result = adapter->Connect(
78       base::Bind(&PseudoTcpChannelFactory::OnPseudoTcpConnected,
79                  base::Unretained(this), name, callback));
80   if (result != net::ERR_IO_PENDING)
81     OnPseudoTcpConnected(name, callback, result);
82 }
83 
OnPseudoTcpConnected(const std::string & name,const ChannelCreatedCallback & callback,int result)84 void PseudoTcpChannelFactory::OnPseudoTcpConnected(
85     const std::string& name,
86     const ChannelCreatedCallback& callback,
87     int result) {
88   PendingSocketsMap::iterator it = pending_sockets_.find(name);
89   DCHECK(it != pending_sockets_.end());
90   scoped_ptr<net::StreamSocket> socket(it->second);
91   pending_sockets_.erase(it);
92 
93   if (result != net::OK)
94     socket.reset();
95 
96   callback.Run(socket.Pass());
97 }
98 
99 }  // namespace protocol
100 }  // namespace remoting
101