1 // Copyright (c) 2008 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.
5 #include "ipc/ipc_channel_posix.h"
10 #include <sys/types.h>
11 #include <sys/socket.h>
18 #include "base/command_line.h"
19 #include "base/eintr_wrapper.h"
20 #include "base/global_descriptors_posix.h"
21 #include "base/lock.h"
22 #include "base/logging.h"
23 #include "base/process_util.h"
24 #include "base/scoped_ptr.h"
25 #include "base/singleton.h"
26 #include "base/stats_counters.h"
27 #include "base/string_util.h"
28 #include "ipc/ipc_descriptors.h"
29 #include "ipc/ipc_switches.h"
30 #include "ipc/file_descriptor_set_posix.h"
31 #include "ipc/ipc_logging.h"
32 #include "ipc/ipc_message_utils.h"
36 // IPC channels on Windows use named pipes (CreateNamedPipe()) with
37 // channel ids as the pipe names. Channels on POSIX use anonymous
38 // Unix domain sockets created via socketpair() as pipes. These don't
41 // When creating a child subprocess, the parent side of the fork
42 // arranges it such that the initial control channel ends up on the
43 // magic file descriptor kPrimaryIPCChannel in the child. Future
44 // connections (file descriptors) can then be passed via that
45 // connection via sendmsg().
47 //------------------------------------------------------------------------------
50 // The PipeMap class works around this quirk related to unit tests:
52 // When running as a server, we install the client socket in a
53 // specific file descriptor number (@kPrimaryIPCChannel). However, we
54 // also have to support the case where we are running unittests in the
55 // same process. (We do not support forking without execing.)
57 // Case 1: normal running
58 // The IPC server object will install a mapping in PipeMap from the
59 // name which it was given to the client pipe. When forking the client, the
60 // GetClientFileDescriptorMapping will ensure that the socket is installed in
61 // the magic slot (@kPrimaryIPCChannel). The client will search for the
62 // mapping, but it won't find any since we are in a new process. Thus the
63 // magic fd number is returned. Once the client connects, the server will
64 // close its copy of the client socket and remove the mapping.
66 // Case 2: unittests - client and server in the same process
67 // The IPC server will install a mapping as before. The client will search
68 // for a mapping and find out. It duplicates the file descriptor and
69 // connects. Once the client connects, the server will close the original
70 // copy of the client socket and remove the mapping. Thus, when the client
71 // object closes, it will close the only remaining copy of the client socket
72 // in the fd table and the server will see EOF on its side.
74 // TODO(port): a client process cannot connect to multiple IPC channels with
79 // Lookup a given channel id. Return -1 if not found.
80 int Lookup(const std::string
& channel_id
) {
81 AutoLock
locked(lock_
);
83 ChannelToFDMap::const_iterator i
= map_
.find(channel_id
);
89 // Remove the mapping for the given channel id. No error is signaled if the
90 // channel_id doesn't exist
91 void RemoveAndClose(const std::string
& channel_id
) {
92 AutoLock
locked(lock_
);
94 ChannelToFDMap::iterator i
= map_
.find(channel_id
);
95 if (i
!= map_
.end()) {
96 HANDLE_EINTR(close(i
->second
));
101 // Insert a mapping from @channel_id to @fd. It's a fatal error to insert a
102 // mapping if one already exists for the given channel_id
103 void Insert(const std::string
& channel_id
, int fd
) {
104 AutoLock
locked(lock_
);
107 ChannelToFDMap::const_iterator i
= map_
.find(channel_id
);
108 CHECK(i
== map_
.end()) << "Creating second IPC server (fd " << fd
<< ") "
109 << "for '" << channel_id
<< "' while first "
110 << "(fd " << i
->second
<< ") still exists";
111 map_
[channel_id
] = fd
;
116 typedef std::map
<std::string
, int> ChannelToFDMap
;
120 // Used to map a channel name to the equivalent FD # in the current process.
121 // Returns -1 if the channel is unknown.
122 int ChannelNameToFD(const std::string
& channel_id
) {
123 // See the large block comment above PipeMap for the reasoning here.
124 const int fd
= Singleton
<PipeMap
>()->Lookup(channel_id
);
127 int dup_fd
= dup(fd
);
129 PLOG(FATAL
) << "dup(" << fd
<< ")";
136 //------------------------------------------------------------------------------
137 sockaddr_un sizecheck
;
138 const size_t kMaxPipeNameLength
= sizeof(sizecheck
.sun_path
);
140 // Creates a Fifo with the specified name ready to listen on.
141 bool CreateServerFifo(const std::string
& pipe_name
, int* server_listen_fd
) {
142 DCHECK(server_listen_fd
);
143 DCHECK_GT(pipe_name
.length(), 0u);
144 DCHECK_LT(pipe_name
.length(), kMaxPipeNameLength
);
146 if (pipe_name
.length() == 0 || pipe_name
.length() >= kMaxPipeNameLength
) {
151 int fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
156 // Make socket non-blocking
157 if (fcntl(fd
, F_SETFL
, O_NONBLOCK
) == -1) {
158 HANDLE_EINTR(close(fd
));
162 // Delete any old FS instances.
163 unlink(pipe_name
.c_str());
165 // Create unix_addr structure
166 struct sockaddr_un unix_addr
;
167 memset(&unix_addr
, 0, sizeof(unix_addr
));
168 unix_addr
.sun_family
= AF_UNIX
;
169 snprintf(unix_addr
.sun_path
, kMaxPipeNameLength
, "%s", pipe_name
.c_str());
170 size_t unix_addr_len
= offsetof(struct sockaddr_un
, sun_path
) +
171 strlen(unix_addr
.sun_path
) + 1;
174 if (bind(fd
, reinterpret_cast<const sockaddr
*>(&unix_addr
),
175 unix_addr_len
) != 0) {
176 HANDLE_EINTR(close(fd
));
180 // Start listening on the socket.
181 const int listen_queue_length
= 1;
182 if (listen(fd
, listen_queue_length
) != 0) {
183 HANDLE_EINTR(close(fd
));
187 *server_listen_fd
= fd
;
191 // Accept a connection on a fifo.
192 bool ServerAcceptFifoConnection(int server_listen_fd
, int* server_socket
) {
193 DCHECK(server_socket
);
195 int accept_fd
= HANDLE_EINTR(accept(server_listen_fd
, NULL
, 0));
198 if (fcntl(accept_fd
, F_SETFL
, O_NONBLOCK
) == -1) {
199 HANDLE_EINTR(close(accept_fd
));
203 *server_socket
= accept_fd
;
207 bool ClientConnectToFifo(const std::string
&pipe_name
, int* client_socket
) {
208 DCHECK(client_socket
);
209 DCHECK_LT(pipe_name
.length(), kMaxPipeNameLength
);
212 int fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
214 LOG(ERROR
) << "fd is invalid";
218 // Make socket non-blocking
219 if (fcntl(fd
, F_SETFL
, O_NONBLOCK
) == -1) {
220 LOG(ERROR
) << "fcntl failed";
221 HANDLE_EINTR(close(fd
));
225 // Create server side of socket.
226 struct sockaddr_un server_unix_addr
;
227 memset(&server_unix_addr
, 0, sizeof(server_unix_addr
));
228 server_unix_addr
.sun_family
= AF_UNIX
;
229 snprintf(server_unix_addr
.sun_path
, kMaxPipeNameLength
, "%s",
231 size_t server_unix_addr_len
= offsetof(struct sockaddr_un
, sun_path
) +
232 strlen(server_unix_addr
.sun_path
) + 1;
234 if (HANDLE_EINTR(connect(fd
, reinterpret_cast<sockaddr
*>(&server_unix_addr
),
235 server_unix_addr_len
)) != 0) {
236 HANDLE_EINTR(close(fd
));
244 bool SocketWriteErrorIsRecoverable() {
245 #if defined(OS_MACOSX)
246 // On OS X if sendmsg() is trying to send fds between processes and there
247 // isn't enough room in the output buffer to send the fd structure over
248 // atomically then EMSGSIZE is returned.
250 // EMSGSIZE presents a problem since the system APIs can only call us when
251 // there's room in the socket buffer and not when there is "enough" room.
253 // The current behavior is to return to the event loop when EMSGSIZE is
254 // received and hopefull service another FD. This is however still
255 // technically a busy wait since the event loop will call us right back until
256 // the receiver has read enough data to allow passing the FD over atomically.
257 return errno
== EAGAIN
|| errno
== EMSGSIZE
;
259 return errno
== EAGAIN
;
264 //------------------------------------------------------------------------------
266 Channel::ChannelImpl::ChannelImpl(const std::string
& channel_id
, Mode mode
,
269 is_blocked_on_write_(false),
270 message_send_bytes_written_(0),
271 uses_fifo_(CommandLine::ForCurrentProcess()->HasSwitch(
272 switches::kIPCUseFIFO
)),
273 server_listen_pipe_(-1),
276 #if defined(OS_LINUX)
281 waiting_connect_(true),
283 if (!CreatePipe(channel_id
, mode
)) {
284 // The pipe may have been closed already.
285 PLOG(WARNING
) << "Unable to create pipe named \"" << channel_id
286 << "\" in " << (mode
== MODE_SERVER
? "server" : "client")
292 void AddChannelSocket(const std::string
& name
, int socket
) {
293 Singleton
<PipeMap
>()->Insert(name
, socket
);
297 void RemoveAndCloseChannelSocket(const std::string
& name
) {
298 Singleton
<PipeMap
>()->RemoveAndClose(name
);
302 bool SocketPair(int* fd1
, int* fd2
) {
304 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, pipe_fds
) != 0) {
305 PLOG(ERROR
) << "socketpair()";
309 // Set both ends to be non-blocking.
310 if (fcntl(pipe_fds
[0], F_SETFL
, O_NONBLOCK
) == -1 ||
311 fcntl(pipe_fds
[1], F_SETFL
, O_NONBLOCK
) == -1) {
312 PLOG(ERROR
) << "fcntl(O_NONBLOCK)";
313 HANDLE_EINTR(close(pipe_fds
[0]));
314 HANDLE_EINTR(close(pipe_fds
[1]));
324 bool Channel::ChannelImpl::CreatePipe(const std::string
& channel_id
,
326 DCHECK(server_listen_pipe_
== -1 && pipe_
== -1);
329 // This only happens in unit tests; see the comment above PipeMap.
330 // TODO(playmobil): We shouldn't need to create fifos on disk.
331 // TODO(playmobil): If we do, they should be in the user data directory.
332 // TODO(playmobil): Cleanup any stale fifos.
333 pipe_name_
= "/var/tmp/chrome_" + channel_id
;
334 if (mode
== MODE_SERVER
) {
335 if (!CreateServerFifo(pipe_name_
, &server_listen_pipe_
)) {
339 if (!ClientConnectToFifo(pipe_name_
, &pipe_
)) {
342 waiting_connect_
= false;
345 // This is the normal (non-unit-test) case, where we're using sockets.
346 // Three possible cases:
347 // 1) It's for a channel we already have a pipe for; reuse it.
348 // 2) It's the initial IPC channel:
349 // 2a) Server side: create the pipe.
350 // 2b) Client side: Pull the pipe out of the GlobalDescriptors set.
351 pipe_name_
= channel_id
;
352 pipe_
= ChannelNameToFD(pipe_name_
);
354 // Initial IPC channel.
355 if (mode
== MODE_SERVER
) {
356 if (!SocketPair(&pipe_
, &client_pipe_
))
358 AddChannelSocket(pipe_name_
, client_pipe_
);
360 // Guard against inappropriate reuse of the initial IPC channel. If
361 // an IPC channel closes and someone attempts to reuse it by name, the
362 // initial channel must not be recycled here. http://crbug.com/26754.
363 static bool used_initial_channel
= false;
364 if (used_initial_channel
) {
365 LOG(FATAL
) << "Denying attempt to reuse initial IPC channel";
368 used_initial_channel
= true;
370 pipe_
= Singleton
<base::GlobalDescriptors
>()->Get(kPrimaryIPCChannel
);
373 waiting_connect_
= mode
== MODE_SERVER
;
377 // Create the Hello message to be sent when Connect is called
378 scoped_ptr
<Message
> msg(new Message(MSG_ROUTING_NONE
,
380 IPC::Message::PRIORITY_NORMAL
));
381 #if defined(OS_LINUX)
383 // On Linux, the seccomp sandbox makes it very expensive to call
384 // recvmsg() and sendmsg(). Often, we are perfectly OK with resorting to
385 // read() and write(), which are cheap.
387 // As we cannot anticipate, when the sender will provide us with file
388 // handles, we have to make the decision about whether we call read() or
389 // recvmsg() before we actually make the call. The easiest option is to
390 // create a dedicated socketpair() for exchanging file handles.
391 if (mode
== MODE_SERVER
) {
393 } else if (remote_fd_pipe_
== -1) {
394 if (!SocketPair(&fd_pipe_
, &remote_fd_pipe_
)) {
400 if (!msg
->WriteInt(base::GetCurrentProcId())) {
405 output_queue_
.push(msg
.release());
409 bool Channel::ChannelImpl::Connect() {
410 if (mode_
== MODE_SERVER
&& uses_fifo_
) {
411 if (server_listen_pipe_
== -1) {
414 MessageLoopForIO::current()->WatchFileDescriptor(
417 MessageLoopForIO::WATCH_READ
,
418 &server_listen_connection_watcher_
,
424 MessageLoopForIO::current()->WatchFileDescriptor(
427 MessageLoopForIO::WATCH_READ
,
430 waiting_connect_
= mode_
== MODE_SERVER
;
433 if (!waiting_connect_
)
434 return ProcessOutgoingMessages();
438 bool Channel::ChannelImpl::ProcessIncomingMessages() {
439 ssize_t bytes_read
= 0;
441 struct msghdr msg
= {0};
442 struct iovec iov
= {input_buf_
, Channel::kReadBufferSize
};
445 msg
.msg_control
= input_cmsg_buf_
;
450 if (bytes_read
== 0) {
455 // recvmsg() returns 0 if the connection has closed or EAGAIN if no data
456 // is waiting on the pipe.
457 #if defined(OS_LINUX)
459 bytes_read
= HANDLE_EINTR(read(pipe_
, input_buf_
,
460 Channel::kReadBufferSize
));
461 msg
.msg_controllen
= 0;
465 msg
.msg_controllen
= sizeof(input_cmsg_buf_
);
466 bytes_read
= HANDLE_EINTR(recvmsg(pipe_
, &msg
, MSG_DONTWAIT
));
468 if (bytes_read
< 0) {
469 if (errno
== EAGAIN
) {
471 #if defined(OS_MACOSX)
472 } else if (errno
== EPERM
) {
473 // On OSX, reading from a pipe with no listener returns EPERM
474 // treat this as a special case to prevent spurious error messages
477 #endif // defined(OS_MACOSX)
478 } else if (errno
== ECONNRESET
|| errno
== EPIPE
) {
481 PLOG(ERROR
) << "pipe error (" << pipe_
<< ")";
484 } else if (bytes_read
== 0) {
485 // The pipe has closed...
491 if (client_pipe_
!= -1) {
492 Singleton
<PipeMap
>()->RemoveAndClose(pipe_name_
);
496 // a pointer to an array of |num_wire_fds| file descriptors from the read
497 const int* wire_fds
= NULL
;
498 unsigned num_wire_fds
= 0;
500 // walk the list of control messages and, if we find an array of file
501 // descriptors, save a pointer to the array
503 // This next if statement is to work around an OSX issue where
504 // CMSG_FIRSTHDR will return non-NULL in the case that controllen == 0.
505 // Here's a test case:
508 // struct msghdr msg;
509 // msg.msg_control = &msg;
510 // msg.msg_controllen = 0;
511 // if (CMSG_FIRSTHDR(&msg))
512 // printf("Bug found!\n");
514 if (msg
.msg_controllen
> 0) {
515 // On OSX, CMSG_FIRSTHDR doesn't handle the case where controllen is 0
516 // and will return a pointer into nowhere.
517 for (struct cmsghdr
* cmsg
= CMSG_FIRSTHDR(&msg
); cmsg
;
518 cmsg
= CMSG_NXTHDR(&msg
, cmsg
)) {
519 if (cmsg
->cmsg_level
== SOL_SOCKET
&&
520 cmsg
->cmsg_type
== SCM_RIGHTS
) {
521 const unsigned payload_len
= cmsg
->cmsg_len
- CMSG_LEN(0);
522 DCHECK(payload_len
% sizeof(int) == 0);
523 wire_fds
= reinterpret_cast<int*>(CMSG_DATA(cmsg
));
524 num_wire_fds
= payload_len
/ 4;
526 if (msg
.msg_flags
& MSG_CTRUNC
) {
527 LOG(ERROR
) << "SCM_RIGHTS message was truncated"
528 << " cmsg_len:" << cmsg
->cmsg_len
530 for (unsigned i
= 0; i
< num_wire_fds
; ++i
)
531 HANDLE_EINTR(close(wire_fds
[i
]));
539 // Process messages from input buffer.
542 if (input_overflow_buf_
.empty()) {
544 end
= p
+ bytes_read
;
546 if (input_overflow_buf_
.size() >
547 static_cast<size_t>(kMaximumMessageSize
- bytes_read
)) {
548 input_overflow_buf_
.clear();
549 LOG(ERROR
) << "IPC message is too big";
552 input_overflow_buf_
.append(input_buf_
, bytes_read
);
553 p
= input_overflow_buf_
.data();
554 end
= p
+ input_overflow_buf_
.size();
557 // A pointer to an array of |num_fds| file descriptors which includes any
558 // fds that have spilled over from a previous read.
559 const int* fds
= NULL
;
560 unsigned num_fds
= 0;
561 unsigned fds_i
= 0; // the index of the first unused descriptor
563 if (input_overflow_fds_
.empty()) {
565 num_fds
= num_wire_fds
;
567 if (num_wire_fds
> 0) {
568 const size_t prev_size
= input_overflow_fds_
.size();
569 input_overflow_fds_
.resize(prev_size
+ num_wire_fds
);
570 memcpy(&input_overflow_fds_
[prev_size
], wire_fds
,
571 num_wire_fds
* sizeof(int));
573 fds
= &input_overflow_fds_
[0];
574 num_fds
= input_overflow_fds_
.size();
578 const char* message_tail
= Message::FindNext(p
, end
);
580 int len
= static_cast<int>(message_tail
- p
);
583 if (m
.header()->num_fds
) {
584 // the message has file descriptors
585 const char* error
= NULL
;
586 if (m
.header()->num_fds
> num_fds
- fds_i
) {
587 // the message has been completely received, but we didn't get
588 // enough file descriptors.
589 #if defined(OS_LINUX)
592 struct iovec fd_pipe_iov
= { &dummy
, 1 };
593 msg
.msg_iov
= &fd_pipe_iov
;
594 msg
.msg_controllen
= sizeof(input_cmsg_buf_
);
595 ssize_t n
= HANDLE_EINTR(recvmsg(fd_pipe_
, &msg
, MSG_DONTWAIT
));
596 if (n
== 1 && msg
.msg_controllen
> 0) {
597 for (struct cmsghdr
* cmsg
= CMSG_FIRSTHDR(&msg
); cmsg
;
598 cmsg
= CMSG_NXTHDR(&msg
, cmsg
)) {
599 if (cmsg
->cmsg_level
== SOL_SOCKET
&&
600 cmsg
->cmsg_type
== SCM_RIGHTS
) {
601 const unsigned payload_len
= cmsg
->cmsg_len
- CMSG_LEN(0);
602 DCHECK(payload_len
% sizeof(int) == 0);
603 wire_fds
= reinterpret_cast<int*>(CMSG_DATA(cmsg
));
604 num_wire_fds
= payload_len
/ 4;
606 if (msg
.msg_flags
& MSG_CTRUNC
) {
607 LOG(ERROR
) << "SCM_RIGHTS message was truncated"
608 << " cmsg_len:" << cmsg
->cmsg_len
610 for (unsigned i
= 0; i
< num_wire_fds
; ++i
)
611 HANDLE_EINTR(close(wire_fds
[i
]));
617 if (input_overflow_fds_
.empty()) {
619 num_fds
= num_wire_fds
;
621 if (num_wire_fds
> 0) {
622 const size_t prev_size
= input_overflow_fds_
.size();
623 input_overflow_fds_
.resize(prev_size
+ num_wire_fds
);
624 memcpy(&input_overflow_fds_
[prev_size
], wire_fds
,
625 num_wire_fds
* sizeof(int));
627 fds
= &input_overflow_fds_
[0];
628 num_fds
= input_overflow_fds_
.size();
632 if (m
.header()->num_fds
> num_fds
- fds_i
)
634 error
= "Message needs unreceived descriptors";
637 if (m
.header()->num_fds
>
638 FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE
) {
639 // There are too many descriptors in this message
640 error
= "Message requires an excessive number of descriptors";
644 LOG(WARNING
) << error
645 << " channel:" << this
646 << " message-type:" << m
.type()
647 << " header()->num_fds:" << m
.header()->num_fds
648 << " num_fds:" << num_fds
649 << " fds_i:" << fds_i
;
650 // close the existing file descriptors so that we don't leak them
651 for (unsigned i
= fds_i
; i
< num_fds
; ++i
)
652 HANDLE_EINTR(close(fds
[i
]));
653 input_overflow_fds_
.clear();
654 // abort the connection
658 m
.file_descriptor_set()->SetDescriptors(
659 &fds
[fds_i
], m
.header()->num_fds
);
660 fds_i
+= m
.header()->num_fds
;
662 #ifdef IPC_MESSAGE_DEBUG_EXTRA
663 DLOG(INFO
) << "received message on channel @" << this <<
664 " with type " << m
.type();
666 if (m
.routing_id() == MSG_ROUTING_NONE
&&
667 m
.type() == HELLO_MESSAGE_TYPE
) {
668 // The Hello message contains only the process id.
671 if (!m
.ReadInt(&iter
, &pid
)) {
674 #if defined(OS_LINUX)
675 if (mode_
== MODE_SERVER
&& !uses_fifo_
) {
676 // On Linux, the Hello message from the client to the server
677 // also contains the fd_pipe_, which will be used for all
678 // subsequent file descriptor passing.
679 DCHECK_EQ(m
.file_descriptor_set()->size(), 1);
680 base::FileDescriptor descriptor
;
681 if (!m
.ReadFileDescriptor(&iter
, &descriptor
)) {
684 fd_pipe_
= descriptor
.fd
;
685 CHECK(descriptor
.auto_close
);
688 listener_
->OnChannelConnected(pid
);
690 listener_
->OnMessageReceived(m
);
694 // Last message is partial.
697 input_overflow_fds_
= std::vector
<int>(&fds
[fds_i
], &fds
[num_fds
]);
699 fds
= &input_overflow_fds_
[0];
700 num_fds
= input_overflow_fds_
.size();
702 input_overflow_buf_
.assign(p
, end
- p
);
703 input_overflow_fds_
= std::vector
<int>(&fds
[fds_i
], &fds
[num_fds
]);
705 // When the input data buffer is empty, the overflow fds should be too. If
706 // this is not the case, we probably have a rogue renderer which is trying
707 // to fill our descriptor table.
708 if (input_overflow_buf_
.empty() && !input_overflow_fds_
.empty()) {
709 // We close these descriptors in Close()
713 bytes_read
= 0; // Get more data.
719 bool Channel::ChannelImpl::ProcessOutgoingMessages() {
720 DCHECK(!waiting_connect_
); // Why are we trying to send messages if there's
722 is_blocked_on_write_
= false;
724 if (output_queue_
.empty()) {
732 // Write out all the messages we can till the write blocks or there are no
733 // more outgoing messages.
734 while (!output_queue_
.empty()) {
735 Message
* msg
= output_queue_
.front();
737 #if defined(OS_LINUX)
738 scoped_ptr
<Message
> hello
;
739 if (remote_fd_pipe_
!= -1 &&
740 msg
->routing_id() == MSG_ROUTING_NONE
&&
741 msg
->type() == HELLO_MESSAGE_TYPE
) {
742 hello
.reset(new Message(MSG_ROUTING_NONE
,
744 IPC::Message::PRIORITY_NORMAL
));
747 if (!msg
->ReadInt(&iter
, &pid
) ||
748 !hello
->WriteInt(pid
)) {
751 DCHECK_EQ(hello
->size(), msg
->size());
752 if (!hello
->WriteFileDescriptor(base::FileDescriptor(remote_fd_pipe_
,
757 DCHECK_EQ(msg
->file_descriptor_set()->size(), 1);
761 size_t amt_to_write
= msg
->size() - message_send_bytes_written_
;
762 DCHECK(amt_to_write
!= 0);
763 const char* out_bytes
= reinterpret_cast<const char*>(msg
->data()) +
764 message_send_bytes_written_
;
766 struct msghdr msgh
= {0};
767 struct iovec iov
= {const_cast<char*>(out_bytes
), amt_to_write
};
771 sizeof(int[FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE
]))];
773 ssize_t bytes_written
= 1;
776 if (message_send_bytes_written_
== 0 &&
777 !msg
->file_descriptor_set()->empty()) {
778 // This is the first chunk of a message which has descriptors to send
779 struct cmsghdr
*cmsg
;
780 const unsigned num_fds
= msg
->file_descriptor_set()->size();
782 DCHECK_LE(num_fds
, FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE
);
784 msgh
.msg_control
= buf
;
785 msgh
.msg_controllen
= CMSG_SPACE(sizeof(int) * num_fds
);
786 cmsg
= CMSG_FIRSTHDR(&msgh
);
787 cmsg
->cmsg_level
= SOL_SOCKET
;
788 cmsg
->cmsg_type
= SCM_RIGHTS
;
789 cmsg
->cmsg_len
= CMSG_LEN(sizeof(int) * num_fds
);
790 msg
->file_descriptor_set()->GetDescriptors(
791 reinterpret_cast<int*>(CMSG_DATA(cmsg
)));
792 msgh
.msg_controllen
= cmsg
->cmsg_len
;
794 // DCHECK_LE above already checks that
795 // num_fds < MAX_DESCRIPTORS_PER_MESSAGE so no danger of overflow.
796 msg
->header()->num_fds
= static_cast<uint16
>(num_fds
);
798 #if defined(OS_LINUX)
800 (msg
->routing_id() != MSG_ROUTING_NONE
||
801 msg
->type() != HELLO_MESSAGE_TYPE
)) {
802 // Only the Hello message sends the file descriptor with the message.
803 // Subsequently, we can send file descriptors on the dedicated
804 // fd_pipe_ which makes Seccomp sandbox operation more efficient.
805 struct iovec fd_pipe_iov
= { const_cast<char *>(""), 1 };
806 msgh
.msg_iov
= &fd_pipe_iov
;
807 fd_written
= fd_pipe_
;
808 bytes_written
= HANDLE_EINTR(sendmsg(fd_pipe_
, &msgh
, MSG_DONTWAIT
));
810 msgh
.msg_controllen
= 0;
811 if (bytes_written
> 0) {
812 msg
->file_descriptor_set()->CommitAll();
818 if (bytes_written
== 1) {
820 #if defined(OS_LINUX)
821 if (mode_
!= MODE_SERVER
&& !uses_fifo_
&&
822 msg
->routing_id() == MSG_ROUTING_NONE
&&
823 msg
->type() == HELLO_MESSAGE_TYPE
) {
824 DCHECK_EQ(msg
->file_descriptor_set()->size(), 1);
826 if (!uses_fifo_
&& !msgh
.msg_controllen
) {
827 bytes_written
= HANDLE_EINTR(write(pipe_
, out_bytes
, amt_to_write
));
831 bytes_written
= HANDLE_EINTR(sendmsg(pipe_
, &msgh
, MSG_DONTWAIT
));
834 if (bytes_written
> 0)
835 msg
->file_descriptor_set()->CommitAll();
837 if (bytes_written
< 0 && !SocketWriteErrorIsRecoverable()) {
838 #if defined(OS_MACOSX)
839 // On OSX writing to a pipe with no listener returns EPERM.
840 if (errno
== EPERM
) {
845 if (errno
== EPIPE
) {
849 PLOG(ERROR
) << "pipe error on "
851 << " Currently writing message of size:"
856 if (static_cast<size_t>(bytes_written
) != amt_to_write
) {
857 if (bytes_written
> 0) {
858 // If write() fails with EAGAIN then bytes_written will be -1.
859 message_send_bytes_written_
+= bytes_written
;
862 // Tell libevent to call us back once things are unblocked.
863 is_blocked_on_write_
= true;
864 MessageLoopForIO::current()->WatchFileDescriptor(
867 MessageLoopForIO::WATCH_WRITE
,
872 message_send_bytes_written_
= 0;
875 #ifdef IPC_MESSAGE_DEBUG_EXTRA
876 DLOG(INFO
) << "sent message @" << msg
<< " on channel @" << this <<
877 " with type " << msg
->type();
879 delete output_queue_
.front();
886 bool Channel::ChannelImpl::Send(Message
* message
) {
887 #ifdef IPC_MESSAGE_DEBUG_EXTRA
888 DLOG(INFO
) << "sending message @" << message
<< " on channel @" << this
889 << " with type " << message
->type()
890 << " (" << output_queue_
.size() << " in queue)";
893 #ifdef IPC_MESSAGE_LOG_ENABLED
894 Logging::current()->OnSendMessage(message
, "");
897 output_queue_
.push(message
);
898 if (!waiting_connect_
) {
899 if (!is_blocked_on_write_
) {
900 if (!ProcessOutgoingMessages())
908 int Channel::ChannelImpl::GetClientFileDescriptor() const {
912 // Called by libevent when we can read from th pipe without blocking.
913 void Channel::ChannelImpl::OnFileCanReadWithoutBlocking(int fd
) {
914 bool send_server_hello_msg
= false;
915 if (waiting_connect_
&& mode_
== MODE_SERVER
) {
917 if (!ServerAcceptFifoConnection(server_listen_pipe_
, &pipe_
)) {
921 // No need to watch the listening socket any longer since only one client
922 // can connect. So unregister with libevent.
923 server_listen_connection_watcher_
.StopWatchingFileDescriptor();
925 // Start watching our end of the socket.
926 MessageLoopForIO::current()->WatchFileDescriptor(
929 MessageLoopForIO::WATCH_READ
,
933 waiting_connect_
= false;
935 // In the case of a socketpair() the server starts listening on its end
936 // of the pipe in Connect().
937 waiting_connect_
= false;
939 send_server_hello_msg
= true;
942 if (!waiting_connect_
&& fd
== pipe_
) {
943 if (!ProcessIncomingMessages()) {
945 listener_
->OnChannelError();
946 // The OnChannelError() call may delete this, so we need to exit now.
951 // If we're a server and handshaking, then we want to make sure that we
952 // only send our handshake message after we've processed the client's.
953 // This gives us a chance to kill the client if the incoming handshake
955 if (send_server_hello_msg
) {
956 ProcessOutgoingMessages();
960 // Called by libevent when we can write to the pipe without blocking.
961 void Channel::ChannelImpl::OnFileCanWriteWithoutBlocking(int fd
) {
962 if (!ProcessOutgoingMessages()) {
964 listener_
->OnChannelError();
968 void Channel::ChannelImpl::Close() {
969 // Close can be called multiple time, so we need to make sure we're
972 // Unregister libevent for the listening socket and close it.
973 server_listen_connection_watcher_
.StopWatchingFileDescriptor();
975 if (server_listen_pipe_
!= -1) {
976 HANDLE_EINTR(close(server_listen_pipe_
));
977 server_listen_pipe_
= -1;
980 // Unregister libevent for the FIFO and close it.
981 read_watcher_
.StopWatchingFileDescriptor();
982 write_watcher_
.StopWatchingFileDescriptor();
984 HANDLE_EINTR(close(pipe_
));
987 if (client_pipe_
!= -1) {
988 Singleton
<PipeMap
>()->RemoveAndClose(pipe_name_
);
991 #if defined(OS_LINUX)
992 if (fd_pipe_
!= -1) {
993 HANDLE_EINTR(close(fd_pipe_
));
996 if (remote_fd_pipe_
!= -1) {
997 HANDLE_EINTR(close(remote_fd_pipe_
));
998 remote_fd_pipe_
= -1;
1004 unlink(pipe_name_
.c_str());
1007 while (!output_queue_
.empty()) {
1008 Message
* m
= output_queue_
.front();
1009 output_queue_
.pop();
1013 // Close any outstanding, received file descriptors
1014 for (std::vector
<int>::iterator
1015 i
= input_overflow_fds_
.begin(); i
!= input_overflow_fds_
.end(); ++i
) {
1016 HANDLE_EINTR(close(*i
));
1018 input_overflow_fds_
.clear();
1021 //------------------------------------------------------------------------------
1022 // Channel's methods simply call through to ChannelImpl.
1023 Channel::Channel(const std::string
& channel_id
, Mode mode
,
1025 : channel_impl_(new ChannelImpl(channel_id
, mode
, listener
)) {
1028 Channel::~Channel() {
1029 delete channel_impl_
;
1032 bool Channel::Connect() {
1033 return channel_impl_
->Connect();
1036 void Channel::Close() {
1037 channel_impl_
->Close();
1040 void Channel::set_listener(Listener
* listener
) {
1041 channel_impl_
->set_listener(listener
);
1044 bool Channel::Send(Message
* message
) {
1045 return channel_impl_
->Send(message
);
1048 int Channel::GetClientFileDescriptor() const {
1049 return channel_impl_
->GetClientFileDescriptor();