mojo_server_endpoint_connector_linux.cc 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // Copyright 2021 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. #include "remoting/host/mojo_ipc/mojo_server_endpoint_connector_linux.h"
  5. #include <sys/socket.h>
  6. #include <memory>
  7. #include "base/check.h"
  8. #include "base/logging.h"
  9. #include "base/task/current_thread.h"
  10. #include "mojo/public/cpp/platform/socket_utils_posix.h"
  11. namespace remoting {
  12. MojoServerEndpointConnectorLinux::MojoServerEndpointConnectorLinux(
  13. Delegate* delegate)
  14. : delegate_(delegate) {
  15. DCHECK(delegate_);
  16. }
  17. MojoServerEndpointConnectorLinux::~MojoServerEndpointConnectorLinux() {
  18. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  19. }
  20. void MojoServerEndpointConnectorLinux::Connect(
  21. mojo::PlatformChannelServerEndpoint server_endpoint) {
  22. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  23. DCHECK(server_endpoint.is_valid());
  24. DCHECK(!pending_server_endpoint_.is_valid());
  25. read_watcher_ =
  26. std::make_unique<base::MessagePumpForIO::FdWatchController>(FROM_HERE);
  27. pending_server_endpoint_ = std::move(server_endpoint);
  28. base::CurrentIOThread::Get()->WatchFileDescriptor(
  29. pending_server_endpoint_.platform_handle().GetFD().get(), false,
  30. base::MessagePumpForIO::WATCH_READ, read_watcher_.get(), this);
  31. }
  32. void MojoServerEndpointConnectorLinux::OnFileCanReadWithoutBlocking(int fd) {
  33. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  34. DCHECK_EQ(pending_server_endpoint_.platform_handle().GetFD().get(), fd);
  35. base::ScopedFD socket;
  36. bool success = mojo::AcceptSocketConnection(fd, &socket);
  37. read_watcher_.reset();
  38. pending_server_endpoint_.reset();
  39. if (!success) {
  40. LOG(ERROR) << "AcceptSocketConnection failed.";
  41. delegate_->OnServerEndpointConnectionFailed();
  42. return;
  43. }
  44. if (!socket.is_valid()) {
  45. LOG(ERROR) << "Socket is invalid.";
  46. delegate_->OnServerEndpointConnectionFailed();
  47. return;
  48. }
  49. ucred unix_peer_identity;
  50. socklen_t len = sizeof(unix_peer_identity);
  51. if (getsockopt(socket.get(), SOL_SOCKET, SO_PEERCRED, &unix_peer_identity,
  52. &len) != 0) {
  53. PLOG(ERROR) << "getsockopt failed.";
  54. delegate_->OnServerEndpointConnectionFailed();
  55. return;
  56. }
  57. mojo::PlatformChannelEndpoint endpoint(
  58. mojo::PlatformHandle(std::move(socket)));
  59. if (!endpoint.is_valid()) {
  60. LOG(ERROR) << "Endpoint is invalid.";
  61. delegate_->OnServerEndpointConnectionFailed();
  62. return;
  63. }
  64. auto connection = std::make_unique<mojo::IsolatedConnection>();
  65. auto message_pipe = connection->Connect(std::move(endpoint));
  66. delegate_->OnServerEndpointConnected(
  67. std::move(connection), std::move(message_pipe), unix_peer_identity.pid);
  68. }
  69. void MojoServerEndpointConnectorLinux::OnFileCanWriteWithoutBlocking(int fd) {
  70. NOTREACHED();
  71. }
  72. // static
  73. std::unique_ptr<MojoServerEndpointConnector>
  74. MojoServerEndpointConnector::Create(Delegate* delegate) {
  75. return std::make_unique<MojoServerEndpointConnectorLinux>(delegate);
  76. }
  77. } // namespace remoting