| // Copyright 2016 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "remoting/protocol/stream_message_pipe_adapter.h" |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "base/bind.h" |
| #include "net/base/net_errors.h" |
| #include "net/traffic_annotation/network_traffic_annotation.h" |
| #include "remoting/base/buffered_socket_writer.h" |
| #include "remoting/base/compound_buffer.h" |
| #include "remoting/protocol/message_serialization.h" |
| #include "remoting/protocol/p2p_stream_socket.h" |
| #include "remoting/protocol/stream_channel_factory.h" |
| |
| namespace remoting::protocol { |
| |
| StreamMessagePipeAdapter::StreamMessagePipeAdapter( |
| std::unique_ptr<P2PStreamSocket> socket, |
| ErrorCallback error_callback) |
| : socket_(std::move(socket)), error_callback_(std::move(error_callback)) { |
| DCHECK(socket_); |
| DCHECK(error_callback_); |
| } |
| |
| StreamMessagePipeAdapter::~StreamMessagePipeAdapter() = default; |
| |
| void StreamMessagePipeAdapter::Start(EventHandler* event_handler) { |
| DCHECK(event_handler); |
| event_handler_ = event_handler; |
| |
| writer_ = std::make_unique<BufferedSocketWriter>(); |
| writer_->Start(base::BindRepeating(&P2PStreamSocket::Write, |
| base::Unretained(socket_.get())), |
| base::BindOnce(&StreamMessagePipeAdapter::CloseOnError, |
| base::Unretained(this))); |
| |
| reader_ = std::make_unique<MessageReader>(); |
| reader_->StartReading(socket_.get(), |
| base::BindRepeating(&EventHandler::OnMessageReceived, |
| base::Unretained(event_handler_)), |
| base::BindOnce(&StreamMessagePipeAdapter::CloseOnError, |
| base::Unretained(this))); |
| |
| event_handler_->OnMessagePipeOpen(); |
| } |
| |
| void StreamMessagePipeAdapter::Send(google::protobuf::MessageLite* message, |
| base::OnceClosure done) { |
| net::NetworkTrafficAnnotationTag traffic_annotation = |
| net::DefineNetworkTrafficAnnotation("stream_message_pipe_adapter", R"( |
| semantics { |
| sender: "Chrome Remote Desktop" |
| description: "Chrome Remote Desktop P2P channel." |
| trigger: "Initiating a Chrome Remote Desktop connection." |
| data: |
| "Chrome Remote Desktop session data, including video and input " |
| "events." |
| destination: OTHER |
| destination_other: |
| "The Chrome Remote Desktop client/host that user is connecting to." |
| } |
| policy { |
| cookies_allowed: NO |
| setting: |
| "This request cannot be stopped in settings, but will not be sent " |
| "if user does not use Chrome Remote Desktop." |
| policy_exception_justification: |
| "Not implemented. 'RemoteAccessHostClientDomainList' and " |
| "'RemoteAccessHostDomainList' policies can limit the domains to " |
| "which a connection can be made, but they cannot be used to block " |
| "the request to all domains. Please refer to help desk for other " |
| "approaches to manage this feature." |
| })"); |
| if (writer_) { |
| writer_->Write(SerializeAndFrameMessage(*message), std::move(done), |
| traffic_annotation); |
| } |
| } |
| |
| void StreamMessagePipeAdapter::CloseOnError(int error) { |
| // Stop reading and writing on error. |
| writer_.reset(); |
| reader_.reset(); |
| |
| if (error == 0) { |
| event_handler_->OnMessagePipeClosed(); |
| } else if (error_callback_) { |
| std::move(error_callback_).Run(error); |
| } |
| } |
| |
| StreamMessageChannelFactoryAdapter::StreamMessageChannelFactoryAdapter( |
| StreamChannelFactory* stream_channel_factory, |
| const ErrorCallback& error_callback) |
| : stream_channel_factory_(stream_channel_factory), |
| error_callback_(error_callback) {} |
| |
| StreamMessageChannelFactoryAdapter::~StreamMessageChannelFactoryAdapter() = |
| default; |
| |
| void StreamMessageChannelFactoryAdapter::CreateChannel( |
| const std::string& name, |
| ChannelCreatedCallback callback) { |
| stream_channel_factory_->CreateChannel( |
| name, |
| base::BindOnce(&StreamMessageChannelFactoryAdapter::OnChannelCreated, |
| base::Unretained(this), std::move(callback))); |
| } |
| |
| void StreamMessageChannelFactoryAdapter::CancelChannelCreation( |
| const std::string& name) { |
| stream_channel_factory_->CancelChannelCreation(name); |
| } |
| |
| void StreamMessageChannelFactoryAdapter::OnChannelCreated( |
| ChannelCreatedCallback callback, |
| std::unique_ptr<P2PStreamSocket> socket) { |
| if (!socket) { |
| error_callback_.Run(net::ERR_FAILED); |
| return; |
| } |
| std::move(callback).Run(std::make_unique<StreamMessagePipeAdapter>( |
| std::move(socket), error_callback_)); |
| } |
| |
| } // namespace remoting::protocol |