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.
5 #include "remoting/protocol/pseudotcp_channel_factory.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"
19 // Value is chosen to balance the extra latency against the reduced
20 // load due to ACK traffic.
21 const int kTcpAckDelayMilliseconds
= 10;
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;
30 PseudoTcpChannelFactory::PseudoTcpChannelFactory(
31 DatagramChannelFactory
* datagram_channel_factory
)
32 : datagram_channel_factory_(datagram_channel_factory
) {
35 PseudoTcpChannelFactory::~PseudoTcpChannelFactory() {
36 // CancelChannelCreation() is expected to be called before destruction.
37 DCHECK(pending_sockets_
.empty());
40 void PseudoTcpChannelFactory::CreateChannel(
41 const std::string
& name
,
42 const ChannelCreatedCallback
& callback
) {
43 datagram_channel_factory_
->CreateChannel(
45 base::Bind(&PseudoTcpChannelFactory::OnDatagramChannelCreated
,
46 base::Unretained(this), name
, callback
));
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
);
55 pending_sockets_
.erase(it
);
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
;
67 adapter
->SetSendBufferSize(kTcpSendBufferSize
);
68 adapter
->SetReceiveBufferSize(kTcpReceiveBufferSize
);
69 adapter
->SetNoDelay(true);
70 adapter
->SetAckDelay(kTcpAckDelayMilliseconds
);
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);
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
);
84 void PseudoTcpChannelFactory::OnPseudoTcpConnected(
85 const std::string
& name
,
86 const ChannelCreatedCallback
& callback
,
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
);
93 if (result
!= net::OK
)
96 callback
.Run(socket
.Pass());
99 } // namespace protocol
100 } // namespace remoting