| /* |
| * Copyright (C) 2022 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "host/commands/cvd/server_client.h" |
| |
| #include <atomic> |
| #include <condition_variable> |
| #include <memory> |
| #include <optional> |
| #include <queue> |
| #include <thread> |
| |
| #include "cvd_server.pb.h" |
| |
| #include "common/libs/fs/shared_fd.h" |
| #include "common/libs/fs/shared_select.h" |
| #include "common/libs/utils/result.h" |
| #include "common/libs/utils/unix_sockets.h" |
| |
| namespace cuttlefish { |
| |
| Result<UnixMessageSocket> GetClient(const SharedFD& client) { |
| UnixMessageSocket result(client); |
| CF_EXPECT(result.EnableCredentials(true), |
| "Unable to enable UnixMessageSocket credentials."); |
| return result; |
| } |
| |
| Result<std::optional<RequestWithStdio>> GetRequest(const SharedFD& client) { |
| UnixMessageSocket reader = |
| CF_EXPECT(GetClient(client), "Couldn't get client"); |
| auto read_result = CF_EXPECT(reader.ReadMessage(), "Couldn't read message"); |
| |
| if (read_result.data.empty()) { |
| LOG(VERBOSE) << "Read empty packet, so the client has probably closed the " |
| "connection."; |
| return {}; |
| }; |
| |
| std::string serialized(read_result.data.begin(), read_result.data.end()); |
| cvd::Request request; |
| CF_EXPECT(request.ParseFromString(serialized), |
| "Unable to parse serialized request proto."); |
| |
| CF_EXPECT(read_result.HasFileDescriptors(), |
| "Missing stdio fds from request."); |
| auto fds = CF_EXPECT(read_result.FileDescriptors(), |
| "Error reading stdio fds from request"); |
| CF_EXPECT(fds.size() == 3 || fds.size() == 4, "Wrong number of FDs, received " |
| << fds.size() |
| << ", wanted 3 or 4"); |
| |
| std::optional<ucred> creds; |
| if (read_result.HasCredentials()) { |
| // TODO(b/198453477): Use Credentials to control command access. |
| creds = CF_EXPECT(read_result.Credentials(), "Failed to get credentials"); |
| LOG(DEBUG) << "Has credentials, uid=" << creds->uid; |
| } |
| |
| return RequestWithStdio(std::move(request), std::move(fds), std::move(creds)); |
| } |
| |
| Result<void> SendResponse(const SharedFD& client, |
| const cvd::Response& response) { |
| std::string serialized; |
| CF_EXPECT(response.SerializeToString(&serialized), |
| "Unable to serialize response proto."); |
| UnixSocketMessage message; |
| message.data = std::vector<char>(serialized.begin(), serialized.end()); |
| |
| UnixMessageSocket writer = |
| CF_EXPECT(GetClient(client), "Couldn't get client"); |
| CF_EXPECT(writer.WriteMessage(message)); |
| return {}; |
| } |
| |
| RequestWithStdio::RequestWithStdio(cvd::Request message, |
| std::vector<SharedFD> fds, |
| std::optional<ucred> creds) |
| : message_(message), fds_(std::move(fds)), creds_(creds) {} |
| |
| const cvd::Request& RequestWithStdio::Message() const { return message_; } |
| |
| const std::vector<SharedFD>& RequestWithStdio::FileDescriptors() const { |
| return fds_; |
| } |
| |
| SharedFD RequestWithStdio::In() const { |
| return fds_.size() > 0 ? fds_[0] : SharedFD(); |
| } |
| |
| SharedFD RequestWithStdio::Out() const { |
| return fds_.size() > 1 ? fds_[1] : SharedFD(); |
| } |
| |
| SharedFD RequestWithStdio::Err() const { |
| return fds_.size() > 2 ? fds_[2] : SharedFD(); |
| } |
| |
| std::optional<SharedFD> RequestWithStdio::Extra() const { |
| return fds_.size() > 3 ? fds_[3] : std::optional<SharedFD>{}; |
| } |
| |
| std::optional<ucred> RequestWithStdio::Credentials() const { return creds_; } |
| |
| } // namespace cuttlefish |