OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef IPC_IPC_CHANNEL_POSIX_H_ | 5 #ifndef IPC_IPC_CHANNEL_POSIX_H_ |
6 #define IPC_IPC_CHANNEL_POSIX_H_ | 6 #define IPC_IPC_CHANNEL_POSIX_H_ |
7 | 7 |
8 #include "ipc/ipc_channel.h" | 8 #include "ipc/ipc_channel.h" |
9 | 9 |
10 #include <sys/socket.h> // for CMSG macros | 10 #include <sys/socket.h> // for CMSG macros |
11 | 11 |
12 #include <queue> | 12 #include <queue> |
13 #include <set> | 13 #include <set> |
14 #include <string> | 14 #include <string> |
15 #include <vector> | 15 #include <vector> |
16 | 16 |
17 #include "base/files/scoped_file.h" | 17 #include "base/files/scoped_file.h" |
18 #include "base/message_loop/message_loop.h" | 18 #include "base/message_loop/message_loop.h" |
19 #include "base/process/process.h" | 19 #include "base/process/process.h" |
20 #include "ipc/ipc_channel_reader.h" | 20 #include "ipc/ipc_channel_reader.h" |
21 #include "ipc/ipc_message_attachment_set.h" | 21 #include "ipc/ipc_message_attachment_set.h" |
22 | 22 |
23 #if !defined(OS_MACOSX) | |
24 // On Linux, the seccomp sandbox makes it very expensive to call | |
25 // recvmsg() and sendmsg(). The restriction on calling read() and write(), which | |
26 // are cheap, is that we can't pass file descriptors over them. | |
27 // | |
28 // As we cannot anticipate when the sender will provide us with file | |
29 // descriptors, we have to make the decision about whether we call read() or | |
30 // recvmsg() before we actually make the call. The easiest option is to | |
31 // create a dedicated socketpair() for exchanging file descriptors. Any file | |
32 // descriptors are split out of a message, with the non-file-descriptor payload | |
33 // going over the normal connection, and the file descriptors being sent | |
34 // separately over the other channel. When read()ing from a channel, we'll | |
35 // notice if the message was supposed to have come with file descriptors and | |
36 // use recvmsg on the other socketpair to retrieve them and combine them | |
37 // back with the rest of the message. | |
38 // | |
39 // Mac can also run in IPC_USES_READWRITE mode if necessary, but at this time | |
40 // doesn't take a performance hit from recvmsg and sendmsg, so it doesn't | |
41 // make sense to waste resources on having the separate dedicated socketpair. | |
42 // It is however useful for debugging between Linux and Mac to be able to turn | |
43 // this switch 'on' on the Mac as well. | |
44 // | |
45 // The HELLO message from the client to the server is always sent using | |
46 // sendmsg because it will contain the file descriptor that the server | |
47 // needs to send file descriptors in later messages. | |
48 #define IPC_USES_READWRITE 1 | |
49 #endif | |
50 | |
51 namespace IPC { | 23 namespace IPC { |
52 | 24 |
53 class IPC_EXPORT ChannelPosix : public Channel, | 25 class IPC_EXPORT ChannelPosix : public Channel, |
54 public internal::ChannelReader, | 26 public internal::ChannelReader, |
55 public base::MessageLoopForIO::Watcher { | 27 public base::MessageLoopForIO::Watcher { |
56 public: | 28 public: |
57 ChannelPosix(const IPC::ChannelHandle& channel_handle, Mode mode, | 29 ChannelPosix(const IPC::ChannelHandle& channel_handle, Mode mode, |
58 Listener* listener); | 30 Listener* listener); |
59 ~ChannelPosix() override; | 31 ~ChannelPosix() override; |
60 | 32 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 void QueueHelloMessage(); | 72 void QueueHelloMessage(); |
101 void CloseFileDescriptors(Message* msg); | 73 void CloseFileDescriptors(Message* msg); |
102 void QueueCloseFDMessage(int fd, int hops); | 74 void QueueCloseFDMessage(int fd, int hops); |
103 | 75 |
104 // ChannelReader implementation. | 76 // ChannelReader implementation. |
105 ReadState ReadData(char* buffer, int buffer_len, int* bytes_read) override; | 77 ReadState ReadData(char* buffer, int buffer_len, int* bytes_read) override; |
106 bool WillDispatchInputMessage(Message* msg) override; | 78 bool WillDispatchInputMessage(Message* msg) override; |
107 bool DidEmptyInputBuffers() override; | 79 bool DidEmptyInputBuffers() override; |
108 void HandleInternalMessage(const Message& msg) override; | 80 void HandleInternalMessage(const Message& msg) override; |
109 | 81 |
110 #if defined(IPC_USES_READWRITE) | |
111 // Reads the next message from the fd_pipe_ and appends them to the | |
112 // input_fds_ queue. Returns false if there was a message receiving error. | |
113 // True means there was a message and it was processed properly, or there was | |
114 // no messages. | |
115 bool ReadFileDescriptorsFromFDPipe(); | |
116 #endif | |
117 | |
118 // Finds the set of file descriptors in the given message. On success, | 82 // Finds the set of file descriptors in the given message. On success, |
119 // appends the descriptors to the input_fds_ member and returns true | 83 // appends the descriptors to the input_fds_ member and returns true |
120 // | 84 // |
121 // Returns false if the message was truncated. In this case, any handles that | 85 // Returns false if the message was truncated. In this case, any handles that |
122 // were sent will be closed. | 86 // were sent will be closed. |
123 bool ExtractFileDescriptorsFromMsghdr(msghdr* msg); | 87 bool ExtractFileDescriptorsFromMsghdr(msghdr* msg); |
124 | 88 |
125 // Closes all handles in the input_fds_ list and clears the list. This is | 89 // Closes all handles in the input_fds_ list and clears the list. This is |
126 // used to clean up handles in error conditions to avoid leaking the handles. | 90 // used to clean up handles in error conditions to avoid leaking the handles. |
127 void ClearInputFDs(); | 91 void ClearInputFDs(); |
(...skipping 26 matching lines...) Expand all Loading... |
154 base::ScopedFD server_listen_pipe_; | 118 base::ScopedFD server_listen_pipe_; |
155 | 119 |
156 // The pipe used for communication. | 120 // The pipe used for communication. |
157 base::ScopedFD pipe_; | 121 base::ScopedFD pipe_; |
158 | 122 |
159 // For a server, the client end of our socketpair() -- the other end of our | 123 // For a server, the client end of our socketpair() -- the other end of our |
160 // pipe_ that is passed to the client. | 124 // pipe_ that is passed to the client. |
161 base::ScopedFD client_pipe_; | 125 base::ScopedFD client_pipe_; |
162 mutable base::Lock client_pipe_lock_; // Lock that protects |client_pipe_|. | 126 mutable base::Lock client_pipe_lock_; // Lock that protects |client_pipe_|. |
163 | 127 |
164 #if defined(IPC_USES_READWRITE) | |
165 // Linux/BSD use a dedicated socketpair() for passing file descriptors. | |
166 base::ScopedFD fd_pipe_; | |
167 base::ScopedFD remote_fd_pipe_; | |
168 #endif | |
169 | |
170 // The "name" of our pipe. On Windows this is the global identifier for | 128 // The "name" of our pipe. On Windows this is the global identifier for |
171 // the pipe. On POSIX it's used as a key in a local map of file descriptors. | 129 // the pipe. On POSIX it's used as a key in a local map of file descriptors. |
172 std::string pipe_name_; | 130 std::string pipe_name_; |
173 | 131 |
174 // Messages to be sent are queued here. | 132 // Messages to be sent are queued here. |
175 std::queue<Message*> output_queue_; | 133 std::queue<Message*> output_queue_; |
176 | 134 |
177 // We assume a worst case: kReadBufferSize bytes of messages, where each | 135 // We assume a worst case: kReadBufferSize bytes of messages, where each |
178 // message has no payload and a full complement of descriptors. | 136 // message has no payload and a full complement of descriptors. |
179 static const size_t kMaxReadFDs = | 137 static const size_t kMaxReadFDs = |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 // If non-zero, overrides the process ID sent in the hello message. | 178 // If non-zero, overrides the process ID sent in the hello message. |
221 static int global_pid_; | 179 static int global_pid_; |
222 #endif // OS_LINUX | 180 #endif // OS_LINUX |
223 | 181 |
224 DISALLOW_IMPLICIT_CONSTRUCTORS(ChannelPosix); | 182 DISALLOW_IMPLICIT_CONSTRUCTORS(ChannelPosix); |
225 }; | 183 }; |
226 | 184 |
227 } // namespace IPC | 185 } // namespace IPC |
228 | 186 |
229 #endif // IPC_IPC_CHANNEL_POSIX_H_ | 187 #endif // IPC_IPC_CHANNEL_POSIX_H_ |
OLD | NEW |