1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <sys/socket.h>
19 
20 #include <cstdint>
21 #include <vector>
22 
23 #include "common/libs/fs/shared_fd.h"
24 #include "common/libs/utils/result.h"
25 
26 namespace cuttlefish {
27 
28 struct ControlMessage {
29  public:
30   static ControlMessage FromRaw(const cmsghdr*);
31   static Result<ControlMessage> FromFileDescriptors(
32       const std::vector<SharedFD>&);
33 #ifdef __linux__
34   static ControlMessage FromCredentials(const ucred&);
35 #endif
36   ControlMessage(const ControlMessage&) = delete;
37   ControlMessage(ControlMessage&&);
38   ~ControlMessage();
39   ControlMessage& operator=(const ControlMessage&) = delete;
40   ControlMessage& operator=(ControlMessage&&);
41 
42   const cmsghdr* Raw() const;
43 
44 #ifdef __linux__
45   bool IsCredentials() const;
46   Result<ucred> AsCredentials() const;
47 #endif
48 
49   bool IsFileDescriptors() const;
50   Result<std::vector<SharedFD>> AsSharedFDs() const;
51 
52  private:
53   friend class UnixMessageSocket;
54   ControlMessage() = default;
55   cmsghdr* Raw();
56 
57   std::vector<char> data_;
58   std::vector<int> fds_;
59 };
60 
61 struct UnixSocketMessage {
62   std::vector<char> data;
63   std::vector<ControlMessage> control;
64 
65   bool HasFileDescriptors();
66   Result<std::vector<SharedFD>> FileDescriptors();
67 #ifdef __linux__
68   bool HasCredentials();
69   Result<ucred> Credentials();
70 #endif
71 };
72 
73 class UnixMessageSocket {
74  public:
75   UnixMessageSocket(SharedFD);
76   [[nodiscard]] Result<void> WriteMessage(const UnixSocketMessage&);
77   Result<UnixSocketMessage> ReadMessage();
78 
79 #ifdef __linux__
80   [[nodiscard]] Result<void> EnableCredentials(bool);
81 #endif
82 
83  private:
84   SharedFD socket_;
85   std::uint32_t max_message_size_;
86 };
87 
88 }  // namespace cuttlefish
89