| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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 | |
| 5 #ifndef IPC_IPC_CHANNEL_POSIX_H_ | |
| 6 #define IPC_IPC_CHANNEL_POSIX_H_ | |
| 7 | |
| 8 #include "ipc/ipc_channel.h" | |
| 9 | |
| 10 #include <stddef.h> | |
| 11 #include <sys/socket.h> // for CMSG macros | |
| 12 | |
| 13 #include <queue> | |
| 14 #include <set> | |
| 15 #include <string> | |
| 16 #include <vector> | |
| 17 | |
| 18 #include "base/files/scoped_file.h" | |
| 19 #include "base/macros.h" | |
| 20 #include "base/message_loop/message_loop.h" | |
| 21 #include "base/process/process.h" | |
| 22 #include "build/build_config.h" | |
| 23 #include "ipc/ipc_channel_reader.h" | |
| 24 #include "ipc/ipc_message_attachment_set.h" | |
| 25 | |
| 26 namespace IPC { | |
| 27 | |
| 28 class IPC_EXPORT ChannelPosix : public Channel, | |
| 29 public internal::ChannelReader, | |
| 30 public base::MessageLoopForIO::Watcher { | |
| 31 public: | |
| 32 // |broker| must outlive the newly created object. | |
| 33 ChannelPosix(const IPC::ChannelHandle& channel_handle, | |
| 34 Mode mode, | |
| 35 Listener* listener); | |
| 36 ~ChannelPosix() override; | |
| 37 | |
| 38 // Channel implementation | |
| 39 bool Connect() override; | |
| 40 void Close() override; | |
| 41 bool Send(Message* message) override; | |
| 42 AttachmentBroker* GetAttachmentBroker() override; | |
| 43 base::ProcessId GetPeerPID() const override; | |
| 44 base::ProcessId GetSelfPID() const override; | |
| 45 int GetClientFileDescriptor() const override; | |
| 46 base::ScopedFD TakeClientFileDescriptor() override; | |
| 47 | |
| 48 // Returns true if the channel supports listening for connections. | |
| 49 bool AcceptsConnections() const; | |
| 50 | |
| 51 // Returns true if the channel supports listening for connections and is | |
| 52 // currently connected. | |
| 53 bool HasAcceptedConnection() const; | |
| 54 | |
| 55 // Closes any currently connected socket, and returns to a listening state | |
| 56 // for more connections. | |
| 57 void ResetToAcceptingConnectionState(); | |
| 58 | |
| 59 // Returns true if the peer process' effective user id can be determined, in | |
| 60 // which case the supplied peer_euid is updated with it. | |
| 61 bool GetPeerEuid(uid_t* peer_euid) const; | |
| 62 | |
| 63 void CloseClientFileDescriptor(); | |
| 64 | |
| 65 static bool IsNamedServerInitialized(const std::string& channel_id); | |
| 66 #if defined(OS_LINUX) | |
| 67 static void SetGlobalPid(int pid); | |
| 68 static int GetGlobalPid(); | |
| 69 #endif // OS_LINUX | |
| 70 | |
| 71 private: | |
| 72 bool CreatePipe(const IPC::ChannelHandle& channel_handle); | |
| 73 | |
| 74 // Returns false on recoverable error. | |
| 75 // There are two reasons why this method might leave messages in the | |
| 76 // output_queue_. | |
| 77 // 1. |waiting_connect_| is |true|. | |
| 78 // 2. |is_blocked_on_write_| is |true|. | |
| 79 // If any of these conditionals change, this method should be called, as | |
| 80 // previously blocked messages may no longer be blocked. | |
| 81 bool ProcessOutgoingMessages(); | |
| 82 | |
| 83 bool OnConnect(); | |
| 84 void ClosePipeOnError(); | |
| 85 int GetHelloMessageProcId() const; | |
| 86 void QueueHelloMessage(); | |
| 87 void CloseFileDescriptors(Message* msg); | |
| 88 void QueueCloseFDMessage(int fd, int hops); | |
| 89 | |
| 90 // ChannelReader implementation. | |
| 91 ReadState ReadData(char* buffer, int buffer_len, int* bytes_read) override; | |
| 92 bool ShouldDispatchInputMessage(Message* msg) override; | |
| 93 bool GetNonBrokeredAttachments(Message* msg) override; | |
| 94 bool DidEmptyInputBuffers() override; | |
| 95 void HandleInternalMessage(const Message& msg) override; | |
| 96 base::ProcessId GetSenderPID() override; | |
| 97 bool IsAttachmentBrokerEndpoint() override; | |
| 98 | |
| 99 // Finds the set of file descriptors in the given message. On success, | |
| 100 // appends the descriptors to the input_fds_ member and returns true | |
| 101 // | |
| 102 // Returns false if the message was truncated. In this case, any handles that | |
| 103 // were sent will be closed. | |
| 104 bool ExtractFileDescriptorsFromMsghdr(msghdr* msg); | |
| 105 | |
| 106 // Closes all handles in the input_fds_ list and clears the list. This is | |
| 107 // used to clean up handles in error conditions to avoid leaking the handles. | |
| 108 void ClearInputFDs(); | |
| 109 | |
| 110 // MessageLoopForIO::Watcher implementation. | |
| 111 void OnFileCanReadWithoutBlocking(int fd) override; | |
| 112 void OnFileCanWriteWithoutBlocking(int fd) override; | |
| 113 | |
| 114 // Returns |false| on channel error. | |
| 115 // If |message| has brokerable attachments, those attachments are passed to | |
| 116 // the AttachmentBroker (which in turn invokes Send()), so this method must | |
| 117 // be re-entrant. | |
| 118 // Adds |message| to |output_queue_| and calls ProcessOutgoingMessages(). | |
| 119 bool ProcessMessageForDelivery(Message* message); | |
| 120 | |
| 121 // Moves all messages from |prelim_queue_| to |output_queue_| by calling | |
| 122 // ProcessMessageForDelivery(). | |
| 123 // Returns |false| on channel error. | |
| 124 bool FlushPrelimQueue(); | |
| 125 | |
| 126 Mode mode_; | |
| 127 | |
| 128 base::ProcessId peer_pid_; | |
| 129 | |
| 130 // After accepting one client connection on our server socket we want to | |
| 131 // stop listening. | |
| 132 base::MessageLoopForIO::FileDescriptorWatcher | |
| 133 server_listen_connection_watcher_; | |
| 134 base::MessageLoopForIO::FileDescriptorWatcher read_watcher_; | |
| 135 base::MessageLoopForIO::FileDescriptorWatcher write_watcher_; | |
| 136 | |
| 137 // Indicates whether we're currently blocked waiting for a write to complete. | |
| 138 bool is_blocked_on_write_; | |
| 139 bool waiting_connect_; | |
| 140 | |
| 141 // If sending a message blocks then we use this variable | |
| 142 // to keep track of where we are. | |
| 143 size_t message_send_bytes_written_; | |
| 144 | |
| 145 // File descriptor we're listening on for new connections if we listen | |
| 146 // for connections. | |
| 147 base::ScopedFD server_listen_pipe_; | |
| 148 | |
| 149 // The pipe used for communication. | |
| 150 base::ScopedFD pipe_; | |
| 151 | |
| 152 // For a server, the client end of our socketpair() -- the other end of our | |
| 153 // pipe_ that is passed to the client. | |
| 154 base::ScopedFD client_pipe_; | |
| 155 mutable base::Lock client_pipe_lock_; // Lock that protects |client_pipe_|. | |
| 156 | |
| 157 // The "name" of our pipe. On Windows this is the global identifier for | |
| 158 // the pipe. On POSIX it's used as a key in a local map of file descriptors. | |
| 159 std::string pipe_name_; | |
| 160 | |
| 161 // Messages not yet ready to be sent are queued here. Messages removed from | |
| 162 // this queue are placed in the output_queue_. The double queue is | |
| 163 // unfortunate, but is necessary because messages with brokerable attachments | |
| 164 // can generate multiple messages to be sent (possibly from other channels). | |
| 165 // Some of these generated messages cannot be sent until |peer_pid_| has been | |
| 166 // configured. | |
| 167 // As soon as |peer_pid| has been configured, there is no longer any need for | |
| 168 // |prelim_queue_|. All messages are flushed, and no new messages are added. | |
| 169 std::queue<Message*> prelim_queue_; | |
| 170 | |
| 171 // Messages to be sent are queued here. | |
| 172 std::queue<OutputElement*> output_queue_; | |
| 173 | |
| 174 // We assume a worst case: kReadBufferSize bytes of messages, where each | |
| 175 // message has no payload and a full complement of descriptors. | |
| 176 static const size_t kMaxReadFDs = | |
| 177 (Channel::kReadBufferSize / sizeof(IPC::Message::Header)) * | |
| 178 MessageAttachmentSet::kMaxDescriptorsPerMessage; | |
| 179 | |
| 180 // Buffer size for file descriptors used for recvmsg. On Mac the CMSG macros | |
| 181 // are not constant so we have to pick a "large enough" padding for headers. | |
| 182 #if defined(OS_MACOSX) | |
| 183 static const size_t kMaxReadFDBuffer = 1024 + sizeof(int) * kMaxReadFDs; | |
| 184 #else | |
| 185 static const size_t kMaxReadFDBuffer = CMSG_SPACE(sizeof(int) * kMaxReadFDs); | |
| 186 #endif | |
| 187 static_assert(kMaxReadFDBuffer <= 8192, | |
| 188 "kMaxReadFDBuffer too big for a stack buffer"); | |
| 189 | |
| 190 // File descriptors extracted from messages coming off of the channel. The | |
| 191 // handles may span messages and come off different channels from the message | |
| 192 // data (in the case of READWRITE), and are processed in FIFO here. | |
| 193 // NOTE: The implementation assumes underlying storage here is contiguous, so | |
| 194 // don't change to something like std::deque<> without changing the | |
| 195 // implementation! | |
| 196 std::vector<int> input_fds_; | |
| 197 | |
| 198 | |
| 199 void ResetSafely(base::ScopedFD* fd); | |
| 200 bool in_dtor_; | |
| 201 | |
| 202 #if defined(OS_MACOSX) | |
| 203 // On OSX, sent FDs must not be closed until we get an ack. | |
| 204 // Keep track of sent FDs here to make sure the remote is not | |
| 205 // trying to bamboozle us. | |
| 206 std::set<int> fds_to_close_; | |
| 207 #endif | |
| 208 | |
| 209 // True if we are responsible for unlinking the unix domain socket file. | |
| 210 bool must_unlink_; | |
| 211 | |
| 212 #if defined(OS_LINUX) | |
| 213 // If non-zero, overrides the process ID sent in the hello message. | |
| 214 static int global_pid_; | |
| 215 #endif // OS_LINUX | |
| 216 | |
| 217 DISALLOW_IMPLICIT_CONSTRUCTORS(ChannelPosix); | |
| 218 }; | |
| 219 | |
| 220 } // namespace IPC | |
| 221 | |
| 222 #endif // IPC_IPC_CHANNEL_POSIX_H_ | |
| OLD | NEW |