Home | History | Annotate | Download | only in protocol
      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 
     30 PseudoTcpChannelFactory::PseudoTcpChannelFactory(
     31     DatagramChannelFactory* datagram_channel_factory)
     32     : datagram_channel_factory_(datagram_channel_factory) {
     33 }
     34 
     35 PseudoTcpChannelFactory::~PseudoTcpChannelFactory() {
     36   // CancelChannelCreation() is expected to be called before destruction.
     37   DCHECK(pending_sockets_.empty());
     38 }
     39 
     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 
     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 
     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 
     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