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 "net/base/net_errors.h"
9 #include "remoting/base/constants.h"
10 #include "remoting/protocol/datagram_channel_factory.h"
11 #include "remoting/protocol/p2p_datagram_socket.h"
12 #include "remoting/protocol/pseudotcp_adapter.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
<P2PDatagramSocket
> datagram_socket
) {
63 PseudoTcpAdapter
* adapter
= new PseudoTcpAdapter(datagram_socket
.Pass());
64 pending_sockets_
[name
] = adapter
;
66 adapter
->SetSendBufferSize(kTcpSendBufferSize
);
67 adapter
->SetReceiveBufferSize(kTcpReceiveBufferSize
);
68 adapter
->SetNoDelay(true);
69 adapter
->SetAckDelay(kTcpAckDelayMilliseconds
);
71 // TODO(sergeyu): This is a hack to improve latency of the video channel.
72 // Consider removing it once we have better flow control implemented.
73 if (name
== kVideoChannelName
)
74 adapter
->SetWriteWaitsForSend(true);
76 int result
= adapter
->Connect(
77 base::Bind(&PseudoTcpChannelFactory::OnPseudoTcpConnected
,
78 base::Unretained(this), name
, callback
));
79 if (result
!= net::ERR_IO_PENDING
)
80 OnPseudoTcpConnected(name
, callback
, result
);
83 void PseudoTcpChannelFactory::OnPseudoTcpConnected(
84 const std::string
& name
,
85 const ChannelCreatedCallback
& callback
,
87 PendingSocketsMap::iterator it
= pending_sockets_
.find(name
);
88 DCHECK(it
!= pending_sockets_
.end());
89 scoped_ptr
<P2PStreamSocket
> socket(it
->second
);
90 pending_sockets_
.erase(it
);
92 if (result
!= net::OK
)
95 callback
.Run(socket
.Pass());
98 } // namespace protocol
99 } // namespace remoting