Bug 1738734 - Directly pass around handles rather than using TransportDescriptor, r=jld,media-playback-reviewers,alwu

This simplifies the logic around descriptors significantly, which is
especially useful considering how few places use the type. There is a
small change required on Windows to create the NamedPipe directly and
transfer around each end's handle, rather than connecting between
processes after the fact.

A named pipe has to be used, rather than an anonymous pipe, as
bidirectional communication is required.

Differential Revision: https://phabricator.services.mozilla.com/D130381
This commit is contained in:
Nika Layzell 2022-01-31 22:26:05 +00:00
parent 02d04be983
commit c45d6350d4
39 changed files with 146 additions and 597 deletions

View File

@ -7,6 +7,7 @@
#define WEBGLCHILD_H_
#include "mozilla/dom/PWebGLChild.h"
#include "mozilla/WeakPtr.h"
#include <string>

View File

@ -8,6 +8,7 @@
#include "gfxTypes.h"
#include "ipc/EnumSerializer.h"
#include "ipc/IPCMessageUtils.h"
#include "mozilla/GfxMessageUtils.h"
#include "mozilla/ipc/IPDLParamTraits.h"
#include "mozilla/ipc/Shmem.h"

View File

@ -18,6 +18,7 @@
#include "nsITimer.h"
#include "nsTArray.h"
#include "nsThreadUtils.h"
#include "nsWindowsHelpers.h"
#include "mozilla/ArrayUtils.h"

View File

@ -11,6 +11,7 @@
#include "mozilla/dom/locks/PLockManagerParent.h"
#include "mozilla/dom/locks/LockRequestParent.h"
#include "mozilla/ipc/PBackgroundSharedTypes.h"
#include "mozilla/WeakPtr.h"
namespace mozilla::dom::locks {

View File

@ -10,7 +10,6 @@
#include "MediaResult.h"
#include "base/process.h"
#include "mozilla/dom/PContent.h"
#include "mozilla/ipc/Transport.h"
#include "mozilla/gmp/PGMPServiceChild.h"
#include "mozilla/MozPromise.h"
#include "nsIAsyncShutdown.h"

View File

@ -47,8 +47,6 @@
# include "mozilla/dom/MediaKeys.h" // MediaKeys::kMediaKeysRequestTopic
#endif
using mozilla::ipc::Transport;
namespace mozilla::gmp {
#ifdef __CLASS__

View File

@ -16,7 +16,6 @@
#include "mozilla/gfx/Point.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/ipc/TaskFactory.h"
#include "mozilla/ipc/Transport.h"
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "nsIObserver.h"

View File

@ -26,12 +26,10 @@
#include "mozilla/StaticPrefs_layers.h"
#include "mozilla/StaticPrefs_layout.h"
#include "mozilla/dom/BrowserParent.h"
#include "mozilla/gfx/2D.h" // for DrawTarget
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/gfx/Rect.h" // for IntSize
#include "mozilla/gfx/gfxVars.h" // for gfxVars
#include "mozilla/ipc/Transport.h" // for Transport
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/gfx/2D.h" // for DrawTarget
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/gfx/Rect.h" // for IntSize
#include "mozilla/gfx/gfxVars.h" // for gfxVars
#include "mozilla/gfx/GPUParent.h"
#include "mozilla/layers/APZCTreeManagerParent.h" // for APZCTreeManagerParent
#include "mozilla/layers/APZSampler.h" // for APZSampler

View File

@ -14,7 +14,6 @@
# include "mozilla/gfx/DeviceManagerDx.h" // for DeviceManagerDx
# include "mozilla/layers/ImageDataSerializer.h"
#endif
#include "mozilla/ipc/Transport.h" // for Transport
#include "mozilla/layers/AnimationHelper.h" // for CompositorAnimationStorage
#include "mozilla/layers/APZCTreeManagerParent.h" // for APZCTreeManagerParent
#include "mozilla/layers/APZUpdater.h" // for APZUpdater

View File

@ -22,7 +22,6 @@
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/ipc/Endpoint.h"
#include "mozilla/ipc/MessageChannel.h" // for MessageChannel, etc
#include "mozilla/ipc/Transport.h" // for Transport
#include "mozilla/layers/CompositableClient.h" // for CompositableChild, etc
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator

View File

@ -15,7 +15,6 @@
#include "mozilla/HalTypes.h" // for hal::THREAD_PRIORITY_COMPOSITOR
#include "mozilla/ipc/Endpoint.h"
#include "mozilla/ipc/MessageChannel.h" // for MessageChannel, etc
#include "mozilla/ipc/Transport.h" // for Transport
#include "mozilla/media/MediaSystemResourceManagerParent.h" // for MediaSystemResourceManagerParent
#include "mozilla/layers/BufferTexture.h"
#include "mozilla/layers/CompositableTransactionParent.h"

View File

@ -9,6 +9,7 @@
#include "gfxConfig.h"
#include "nsDebugImpl.h"
#include "nsThreadManager.h"
#include "nsPrintfCString.h"
#include "mozilla/dom/MemoryReportRequest.h"
#include "mozilla/gfx/gfxVars.h"

View File

@ -13,7 +13,6 @@
#include "base/waitable_event.h"
#include "mozilla/ipc/ProcessChild.h"
#include "mozilla/ipc/BrowserProcessSubThread.h"
#include "mozilla/ipc/Transport.h"
typedef mozilla::ipc::BrowserProcessSubThread ChromeThread;
#include "chrome/common/process_watcher.h"

View File

@ -12,6 +12,7 @@
#include "base/basictypes.h"
#include "build/build_config.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/UniquePtrExtensions.h"
#include "mozilla/WeakPtr.h"
#include "chrome/common/ipc_message.h"
@ -40,6 +41,10 @@ class Channel {
struct ChannelId {};
#endif
// For channels which are created after initialization, handles to the pipe
// endpoints may be passed around directly using IPC messages.
using ChannelHandle = mozilla::UniqueFileHandle;
// Implemented by consumers of a Channel to receive messages.
//
// All listeners will only be called on the IO thread, and must be destroyed
@ -97,17 +102,8 @@ class Channel {
//
Channel(const ChannelId& channel_id, Mode mode, Listener* listener);
// XXX it would nice not to have yet more platform-specific code in
// here but it's just not worth the trouble.
#if defined(OS_POSIX)
// Connect to a pre-created channel |fd| as |mode|.
Channel(int fd, Mode mode, Listener* listener);
#elif defined(OS_WIN)
// Connect to a pre-created channel as |mode|. Clients connect to
// the pre-existing server pipe, and servers take over |server_pipe|.
Channel(const ChannelId& channel_id, void* server_pipe, Mode mode,
Listener* listener);
#endif
// Initialize a pre-created channel |pipe| as |mode|.
Channel(ChannelHandle pipe, Mode mode, Listener* listener);
~Channel();
@ -157,9 +153,6 @@ class Channel {
// Return the file descriptor for communication with the peer.
int GetFileDescriptor() const;
// Reset the file descriptor for communication with the peer.
void ResetFileDescriptor(int fd);
// Close the client side of the socketpair.
void CloseClientFileDescriptor();
@ -174,9 +167,6 @@ class Channel {
# endif
#elif defined(OS_WIN)
// Return the server pipe handle.
void* GetServerPipeHandle() const;
// Tell this pipe to accept handles. Exactly one side of the IPC connection
// must be set as `MODE_SERVER`, and that side will be responsible for calling
// `DuplicateHandle` to transfer the handle between processes.
@ -200,6 +190,10 @@ class Channel {
static void SetClientChannelFd(int fd);
#endif // defined(MOZ_WIDGET_ANDROID)
// Create a new pair of pipe endpoints which can be used to establish a
// native IPC::Channel connection.
static bool CreateRawPipe(ChannelHandle* server, ChannelHandle* client);
private:
// PIMPL to which all channel calls are delegated.
class ChannelImpl;

View File

@ -97,16 +97,6 @@ static int gClientChannelFd =
//------------------------------------------------------------------------------
const size_t kMaxPipeNameLength = sizeof(((sockaddr_un*)0)->sun_path);
bool SetCloseOnExec(int fd) {
int flags = fcntl(fd, F_GETFD);
if (flags == -1) return false;
flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, flags) == -1) return false;
return true;
}
bool ErrorIsBrokenPipe(int err) { return err == EPIPE || err == ECONNRESET; }
// Some Android ARM64 devices appear to have a bug where sendmsg
@ -168,10 +158,11 @@ Channel::ChannelImpl::ChannelImpl(const ChannelId& channel_id, Mode mode,
EnqueueHelloMessage();
}
Channel::ChannelImpl::ChannelImpl(int fd, Mode mode, Listener* listener)
Channel::ChannelImpl::ChannelImpl(ChannelHandle pipe, Mode mode,
Listener* listener)
: factory_(this) {
Init(mode, listener);
SetPipe(fd);
SetPipe(pipe.release());
EnqueueHelloMessage();
}
@ -230,33 +221,13 @@ bool Channel::ChannelImpl::CreatePipe(Mode mode) {
DCHECK(server_listen_pipe_ == -1 && pipe_ == -1);
if (mode == MODE_SERVER) {
// socketpair()
int pipe_fds[2];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) {
mozilla::ipc::AnnotateCrashReportWithErrno(
CrashReporter::Annotation::IpcCreatePipeSocketPairErrno, errno);
return false;
}
// Set both ends to be non-blocking.
if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 ||
fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) {
mozilla::ipc::AnnotateCrashReportWithErrno(
CrashReporter::Annotation::IpcCreatePipeFcntlErrno, errno);
IGNORE_EINTR(close(pipe_fds[0]));
IGNORE_EINTR(close(pipe_fds[1]));
ChannelHandle server, client;
if (!Channel::CreateRawPipe(&server, &client)) {
return false;
}
if (!SetCloseOnExec(pipe_fds[0]) || !SetCloseOnExec(pipe_fds[1])) {
mozilla::ipc::AnnotateCrashReportWithErrno(
CrashReporter::Annotation::IpcCreatePipeCloExecErrno, errno);
IGNORE_EINTR(close(pipe_fds[0]));
IGNORE_EINTR(close(pipe_fds[1]));
return false;
}
SetPipe(pipe_fds[0]);
client_pipe_ = pipe_fds[1];
SetPipe(server.release());
client_pipe_ = client.release();
} else {
static mozilla::Atomic<bool> consumed(false);
CHECK(!consumed.exchange(true))
@ -267,15 +238,6 @@ bool Channel::ChannelImpl::CreatePipe(Mode mode) {
return true;
}
/**
* Reset the file descriptor for communication with the peer.
*/
void Channel::ChannelImpl::ResetFileDescriptor(int fd) {
NS_ASSERTION(fd > 0 && fd == pipe_, "Invalid file descriptor");
EnqueueHelloMessage();
}
bool Channel::ChannelImpl::EnqueueHelloMessage() {
mozilla::UniquePtr<Message> msg(
new Message(MSG_ROUTING_NONE, HELLO_MESSAGE_TYPE));
@ -1215,8 +1177,8 @@ Channel::Channel(const ChannelId& channel_id, Mode mode, Listener* listener)
MOZ_COUNT_CTOR(IPC::Channel);
}
Channel::Channel(int fd, Mode mode, Listener* listener)
: channel_impl_(new ChannelImpl(fd, mode, listener)) {
Channel::Channel(ChannelHandle pipe, Mode mode, Listener* listener)
: channel_impl_(new ChannelImpl(std::move(pipe), mode, listener)) {
MOZ_COUNT_CTOR(IPC::Channel);
}
@ -1241,10 +1203,6 @@ void Channel::GetClientFileDescriptorMapping(int* src_fd, int* dest_fd) const {
return channel_impl_->GetClientFileDescriptorMapping(src_fd, dest_fd);
}
void Channel::ResetFileDescriptor(int fd) {
channel_impl_->ResetFileDescriptor(fd);
}
int Channel::GetFileDescriptor() const {
return channel_impl_->GetFileDescriptor();
}
@ -1279,4 +1237,48 @@ Channel::ChannelId Channel::GenerateVerifiedChannelID() { return {}; }
// static
Channel::ChannelId Channel::ChannelIDForCurrentProcess() { return {}; }
// static
bool Channel::CreateRawPipe(ChannelHandle* server, ChannelHandle* client) {
int fds[2];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
mozilla::ipc::AnnotateCrashReportWithErrno(
CrashReporter::Annotation::IpcCreatePipeSocketPairErrno, errno);
return false;
}
auto configureFd = [](int fd) -> bool {
// Mark the endpoints as non-blocking
if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
mozilla::ipc::AnnotateCrashReportWithErrno(
CrashReporter::Annotation::IpcCreatePipeFcntlErrno, errno);
return false;
}
// Mark the pipes as FD_CLOEXEC
int flags = fcntl(fd, F_GETFD);
if (flags == -1) {
mozilla::ipc::AnnotateCrashReportWithErrno(
CrashReporter::Annotation::IpcCreatePipeCloExecErrno, errno);
return false;
}
flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, flags) == -1) {
mozilla::ipc::AnnotateCrashReportWithErrno(
CrashReporter::Annotation::IpcCreatePipeCloExecErrno, errno);
return false;
}
return true;
};
if (!configureFd(fds[0]) || !configureFd(fds[1])) {
IGNORE_EINTR(close(fds[0]));
IGNORE_EINTR(close(fds[1]));
return false;
}
server->reset(fds[0]);
client->reset(fds[1]);
return true;
}
} // namespace IPC

View File

@ -34,7 +34,7 @@ class Channel::ChannelImpl : public MessageLoopForIO::Watcher {
// Mirror methods of Channel, see ipc_channel.h for description.
ChannelImpl(const ChannelId& channel_id, Mode mode, Listener* listener);
ChannelImpl(int fd, Mode mode, Listener* listener);
ChannelImpl(ChannelHandle pipe, Mode mode, Listener* listener);
~ChannelImpl() { Close(); }
bool Connect();
void Close();
@ -46,8 +46,6 @@ class Channel::ChannelImpl : public MessageLoopForIO::Watcher {
bool Send(mozilla::UniquePtr<Message> message);
void GetClientFileDescriptorMapping(int* src_fd, int* dest_fd) const;
void ResetFileDescriptor(int fd);
int GetFileDescriptor() const { return pipe_; }
void CloseClientFileDescriptor();

View File

@ -22,6 +22,7 @@
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/Atomics.h"
#include "mozilla/LateWriteChecks.h"
#include "mozilla/RandomNum.h"
#include "nsThreadUtils.h"
#ifdef FUZZING
@ -72,27 +73,22 @@ Channel::ChannelImpl::ChannelImpl(const ChannelId& channel_id, Mode mode,
}
}
Channel::ChannelImpl::ChannelImpl(const ChannelId& channel_id,
HANDLE server_pipe, Mode mode,
Channel::ChannelImpl::ChannelImpl(ChannelHandle pipe, Mode mode,
Listener* listener)
: ALLOW_THIS_IN_INITIALIZER_LIST(input_state_(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(output_state_(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) {
Init(mode, listener);
if (mode == MODE_SERVER) {
// We don't need the pipe name because we've been passed a handle, but we do
// need to get the shared secret from the channel_id.
PipeName(channel_id, &shared_secret_);
waiting_for_shared_secret_ = !!shared_secret_;
// Use the existing handle that was dup'd to us
pipe_ = server_pipe;
EnqueueHelloMessage();
} else {
// Take the normal init path to connect to the server pipe
CreatePipe(channel_id, mode);
if (!pipe) {
closed_ = true;
return;
}
shared_secret_ = 0;
waiting_for_shared_secret_ = false;
pipe_ = pipe.release();
EnqueueHelloMessage();
}
void Channel::ChannelImpl::Init(Mode mode, Listener* listener) {
@ -124,8 +120,6 @@ void Channel::ChannelImpl::OutputQueuePop() {
output_queue_length_--;
}
HANDLE Channel::ChannelImpl::GetServerPipeHandle() const { return pipe_; }
void Channel::ChannelImpl::Close() {
ASSERT_OWNINGTHREAD(ChannelImpl);
@ -763,9 +757,8 @@ Channel::Channel(const ChannelId& channel_id, Mode mode, Listener* listener)
MOZ_COUNT_CTOR(IPC::Channel);
}
Channel::Channel(const ChannelId& channel_id, void* server_pipe, Mode mode,
Listener* listener)
: channel_impl_(new ChannelImpl(channel_id, server_pipe, mode, listener)) {
Channel::Channel(ChannelHandle pipe, Mode mode, Listener* listener)
: channel_impl_(new ChannelImpl(std::move(pipe), mode, listener)) {
MOZ_COUNT_CTOR(IPC::Channel);
}
@ -778,10 +771,6 @@ bool Channel::Connect() { return channel_impl_->Connect(); }
void Channel::Close() { channel_impl_->Close(); }
void* Channel::GetServerPipeHandle() const {
return channel_impl_->GetServerPipeHandle();
}
void Channel::StartAcceptingHandles(Mode mode) {
channel_impl_->StartAcceptingHandles(mode);
}
@ -832,4 +821,50 @@ Channel::ChannelId Channel::ChannelIDForCurrentProcess() {
switches::kProcessChannelID);
}
// static
bool Channel::CreateRawPipe(ChannelHandle* server, ChannelHandle* client) {
std::wstring pipe_name =
StringPrintf(L"\\\\.\\pipe\\gecko.%lu.%lu.%I64u", ::GetCurrentProcessId(),
::GetCurrentThreadId(), mozilla::RandomUint64OrDie());
const DWORD kOpenMode =
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE;
const DWORD kPipeMode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE;
*server = mozilla::UniqueFileHandle(
::CreateNamedPipeW(pipe_name.c_str(), kOpenMode, kPipeMode,
1, // Max instances.
Channel::kReadBufferSize, // Output buffer size.
Channel::kReadBufferSize, // Input buffer size.
5000, // Timeout in ms.
nullptr)); // Default security descriptor.
if (!server) {
NS_WARNING(
nsPrintfCString("CreateNamedPipeW Failed %u", ::GetLastError()).get());
return false;
}
const DWORD kDesiredAccess = GENERIC_READ | GENERIC_WRITE;
// The SECURITY_ANONYMOUS flag means that the server side cannot impersonate
// the client, which is useful as both server & client may be unprivileged.
const DWORD kFlags =
SECURITY_SQOS_PRESENT | SECURITY_ANONYMOUS | FILE_FLAG_OVERLAPPED;
*client = mozilla::UniqueFileHandle(
::CreateFileW(pipe_name.c_str(), kDesiredAccess, 0, nullptr,
OPEN_EXISTING, kFlags, nullptr));
if (!client) {
NS_WARNING(
nsPrintfCString("CreateFileW Failed %u", ::GetLastError()).get());
return false;
}
// Since a client has connected, ConnectNamedPipe() should return zero and
// GetLastError() should return ERROR_PIPE_CONNECTED.
if (::ConnectNamedPipe(server->get(), nullptr) ||
::GetLastError() != ERROR_PIPE_CONNECTED) {
NS_WARNING(
nsPrintfCString("ConnectNamedPipe Failed %u", ::GetLastError()).get());
return false;
}
return true;
}
} // namespace IPC

View File

@ -26,11 +26,11 @@ namespace IPC {
class Channel::ChannelImpl : public MessageLoopForIO::IOHandler {
public:
using ChannelId = Channel::ChannelId;
using ChannelHandle = Channel::ChannelHandle;
// Mirror methods of Channel, see ipc_channel.h for description.
ChannelImpl(const ChannelId& channel_id, Mode mode, Listener* listener);
ChannelImpl(const ChannelId& channel_id, HANDLE server_pipe, Mode mode,
Listener* listener);
ChannelImpl(ChannelHandle pipe, Mode mode, Listener* listener);
~ChannelImpl() {
if (pipe_ != INVALID_HANDLE_VALUE ||
other_process_ != INVALID_HANDLE_VALUE) {
@ -39,7 +39,6 @@ class Channel::ChannelImpl : public MessageLoopForIO::IOHandler {
}
bool Connect();
void Close();
HANDLE GetServerPipeHandle() const;
void StartAcceptingHandles(Mode mode);
Listener* set_listener(Listener* listener) {
Listener* old = listener_;

View File

@ -1,57 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ipc/AutoTransportDescriptor.h"
#include "mozilla/ResultExtensions.h"
#include "mozilla/ipc/Transport.h"
namespace mozilla::ipc {
AutoTransportDescriptor::AutoTransportDescriptor(
AutoTransportDescriptor&& aOther) noexcept
: mTransport(aOther.mTransport), mValid(aOther.mValid) {
aOther.mValid = false;
}
AutoTransportDescriptor& AutoTransportDescriptor::operator=(
AutoTransportDescriptor&& aOther) noexcept {
if (mValid) {
CloseDescriptor(mTransport);
}
mValid = std::exchange(aOther.mValid, false);
mTransport = aOther.mTransport;
return *this;
}
AutoTransportDescriptor::~AutoTransportDescriptor() {
if (mValid) {
CloseDescriptor(mTransport);
}
}
Result<std::pair<AutoTransportDescriptor, AutoTransportDescriptor>, nsresult>
AutoTransportDescriptor::Create() {
TransportDescriptor one, two;
MOZ_TRY(CreateTransport(&one, &two));
return std::pair{AutoTransportDescriptor(one), AutoTransportDescriptor(two)};
}
AutoTransportDescriptor AutoTransportDescriptor::Duplicate() const {
if (mValid) {
return AutoTransportDescriptor{DuplicateDescriptor(mTransport)};
}
return {};
}
UniquePtr<Transport> AutoTransportDescriptor::Open(Transport::Mode aMode) {
if (mValid) {
mValid = false;
return OpenDescriptor(mTransport, aMode);
}
return nullptr;
}
} // namespace mozilla::ipc

View File

@ -1,84 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_AutoTransportDescriptor_h
#define mozilla_ipc_AutoTransportDescriptor_h
#include <utility>
#include "mozilla/ipc/Transport.h"
#include "mozilla/Result.h"
namespace mozilla::ipc {
class AutoTransportDescriptor final {
public:
AutoTransportDescriptor() = default;
explicit AutoTransportDescriptor(TransportDescriptor aTransport)
: mTransport(aTransport), mValid(true) {}
~AutoTransportDescriptor();
AutoTransportDescriptor(AutoTransportDescriptor&& aOther) noexcept;
AutoTransportDescriptor& operator=(AutoTransportDescriptor&& aOther) noexcept;
static Result<std::pair<AutoTransportDescriptor, AutoTransportDescriptor>,
nsresult>
Create();
AutoTransportDescriptor Duplicate() const;
// NOTE: This will consume this transport descriptor, making it invalid.
UniquePtr<Transport> Open(Transport::Mode aMode);
explicit operator bool() const { return mValid; }
private:
friend struct IPC::ParamTraits<AutoTransportDescriptor>;
TransportDescriptor mTransport;
bool mValid = false;
};
} // namespace mozilla::ipc
namespace IPC {
template <>
struct ParamTraits<mozilla::ipc::AutoTransportDescriptor> {
using paramType = mozilla::ipc::AutoTransportDescriptor;
static void Write(Message* aMsg, paramType&& aParam) {
WriteParam(aMsg, aParam.mValid);
if (aParam.mValid) {
// TransportDescriptor's serialization code takes it by `const T&`,
// however, it actually closes the handles when passed, so we need to mark
// our state as invalid after sending.
WriteParam(aMsg, aParam.mTransport);
aParam.mValid = false;
}
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
bool valid = false;
if (!ReadParam(aMsg, aIter, &valid)) {
return false;
}
if (!valid) {
*aResult = mozilla::ipc::AutoTransportDescriptor{};
return true;
}
mozilla::ipc::TransportDescriptor descr;
if (!ReadParam(aMsg, aIter, &descr)) {
return false;
}
*aResult = mozilla::ipc::AutoTransportDescriptor{descr};
return true;
}
};
} // namespace IPC
#endif

View File

@ -8,7 +8,6 @@
#define mozilla_ipc_backgroundchild_h__
#include "mozilla/Attributes.h"
#include "mozilla/ipc/Transport.h"
class nsIEventTarget;
@ -65,8 +64,6 @@ class BackgroundChild final {
friend class mozilla::dom::ContentProcess;
friend class mozilla::net::SocketProcessChild;
typedef mozilla::ipc::Transport Transport;
public:
// See above.
static PBackgroundChild* GetForCurrentThread();

View File

@ -255,7 +255,6 @@ class ChildImpl final : public BackgroundChildImpl {
friend class mozilla::ipc::BackgroundStarterChild;
typedef base::ProcessId ProcessId;
typedef mozilla::ipc::Transport Transport;
class ShutdownObserver;

View File

@ -9,7 +9,6 @@
#include "base/process.h"
#include "mozilla/Attributes.h"
#include "mozilla/ipc/Transport.h"
#include "nsTArrayForwardDeclare.h"
#ifdef DEBUG
@ -55,7 +54,6 @@ class BackgroundParent final {
typedef base::ProcessId ProcessId;
typedef mozilla::dom::BlobImpl BlobImpl;
typedef mozilla::dom::ContentParent ContentParent;
typedef mozilla::ipc::Transport Transport;
public:
// This function allows the caller to determine if the given parent actor

View File

@ -16,7 +16,6 @@
#include "mozilla/UniquePtr.h"
#include "mozilla/ipc/MessageLink.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/ipc/Transport.h"
#include "mozilla/ipc/NodeController.h"
#include "mozilla/ipc/ScopedPort.h"
#include "nsXULAppAPI.h"

View File

@ -24,7 +24,6 @@
#include <vector>
#include "MessageLink.h" // for HasResultCodes
#include "mozilla/ipc/Transport.h"
#include "mozilla/ipc/ScopedPort.h"
class MessageLoop;
@ -144,7 +143,6 @@ class MessageChannel : HasResultCodes {
static constexpr int32_t kNoTimeout = INT32_MIN;
typedef IPC::Message Message;
typedef mozilla::ipc::Transport Transport;
using ScopedPort = mozilla::ipc::ScopedPort;
explicit MessageChannel(const char* aName, IToplevelProtocol* aListener);

View File

@ -14,7 +14,6 @@
#include "mojo/core/ports/port_ref.h"
#include "mozilla/Assertions.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/ipc/Transport.h"
#include "mozilla/ipc/ScopedPort.h"
namespace IPC {

View File

@ -19,7 +19,7 @@ struct IPC::ParamTraits<mozilla::ipc::NodeChannel::Introduction> {
using paramType = mozilla::ipc::NodeChannel::Introduction;
static void Write(Message* aMsg, paramType&& aParam) {
WriteParam(aMsg, aParam.mName);
WriteParam(aMsg, std::move(aParam.mTransport));
WriteParam(aMsg, std::move(aParam.mHandle));
WriteParam(aMsg, aParam.mMode);
WriteParam(aMsg, aParam.mMyPid);
WriteParam(aMsg, aParam.mOtherPid);
@ -27,7 +27,7 @@ struct IPC::ParamTraits<mozilla::ipc::NodeChannel::Introduction> {
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
return ReadParam(aMsg, aIter, &aResult->mName) &&
ReadParam(aMsg, aIter, &aResult->mTransport) &&
ReadParam(aMsg, aIter, &aResult->mHandle) &&
ReadParam(aMsg, aIter, &aResult->mMode) &&
ReadParam(aMsg, aIter, &aResult->mMyPid) &&
ReadParam(aMsg, aIter, &aResult->mOtherPid);

View File

@ -12,8 +12,6 @@
#include "chrome/common/ipc_message.h"
#include "chrome/common/ipc_channel.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/ipc/AutoTransportDescriptor.h"
#include "mozilla/ipc/Transport.h"
#include "nsISupports.h"
#include "nsTHashMap.h"
#include "mozilla/Queue.h"
@ -37,8 +35,8 @@ class NodeChannel final : public IPC::Channel::Listener {
struct Introduction {
NodeName mName;
AutoTransportDescriptor mTransport;
Transport::Mode mMode;
IPC::Channel::ChannelHandle mHandle;
IPC::Channel::Mode mMode;
int32_t mMyPid = -1;
int32_t mOtherPid = -1;
};

View File

@ -15,7 +15,6 @@
#include "mozilla/StaticPtr.h"
#include "mozilla/Assertions.h"
#include "mozilla/ToString.h"
#include "mozilla/ipc/AutoTransportDescriptor.h"
#include "mozilla/ipc/BrowserProcessSubThread.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/mozalloc.h"
@ -592,9 +591,7 @@ void NodeController::OnIntroduce(const NodeName& aFromNode,
MOZ_ASSERT(aIntroduction.mMyPid == base::GetCurrentProcId(),
"We're the wrong process to receive this?");
UniquePtr<IPC::Channel> channel =
aIntroduction.mTransport.Open(aIntroduction.mMode);
if (!channel) {
if (!aIntroduction.mHandle) {
NODECONTROLLER_WARNING("Could not be introduced to peer %s",
ToString(aIntroduction.mName).c_str());
mNode->LostConnectionToNode(aIntroduction.mName);
@ -604,6 +601,8 @@ void NodeController::OnIntroduce(const NodeName& aFromNode,
return;
}
auto channel = MakeUnique<IPC::Channel>(std::move(aIntroduction.mHandle),
aIntroduction.mMode, nullptr);
auto nodeChannel = MakeRefPtr<NodeChannel>(
aIntroduction.mName, std::move(channel), this, aIntroduction.mOtherPid);
@ -661,8 +660,8 @@ void NodeController::OnRequestIntroduction(const NodeName& aFromNode,
}
RefPtr<NodeChannel> peerB = GetNodeChannel(aName);
auto result = AutoTransportDescriptor::Create();
if (!peerB || result.isErr()) {
IPC::Channel::ChannelHandle handleA, handleB;
if (!peerB || !IPC::Channel::CreateRawPipe(&handleA, &handleB)) {
NODECONTROLLER_WARNING(
"Rejecting introduction request from '%s' for unknown peer '%s'",
ToString(aFromNode).c_str(), ToString(aName).c_str());
@ -670,18 +669,16 @@ void NodeController::OnRequestIntroduction(const NodeName& aFromNode,
// We don't know this peer, or ran into issues creating the descriptor! Send
// an invalid introduction to content to clean up any pending outbound
// messages.
NodeChannel::Introduction intro{aName, AutoTransportDescriptor{},
IPC::Channel::MODE_SERVER,
NodeChannel::Introduction intro{aName, nullptr, IPC::Channel::MODE_SERVER,
peerA->OtherPid(), -1};
peerA->Introduce(std::move(intro));
return;
}
auto [descrA, descrB] = result.unwrap();
NodeChannel::Introduction introA{aName, std::move(descrA),
NodeChannel::Introduction introA{aName, std::move(handleA),
IPC::Channel::MODE_SERVER, peerA->OtherPid(),
peerB->OtherPid()};
NodeChannel::Introduction introB{aFromNode, std::move(descrB),
NodeChannel::Introduction introB{aFromNode, std::move(handleB),
IPC::Channel::MODE_CLIENT, peerB->OtherPid(),
peerA->OtherPid()};
peerA->Introduce(std::move(introA));

View File

@ -16,7 +16,6 @@
#include "mozilla/Assertions.h"
#include "mozilla/ipc/Endpoint.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/ipc/Transport.h"
class PickleIterator;

View File

@ -18,7 +18,6 @@
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/ipc/MessageChannel.h"
#include "mozilla/ipc/Transport.h"
#include "mozilla/ipc/IPDLParamTraits.h"
#include "mozilla/StaticMutex.h"
#if defined(DEBUG) || defined(FUZZING)

View File

@ -34,9 +34,6 @@
#include "nsTArrayForwardDeclare.h"
#include "nsTHashSet.h"
// XXX Things that could be replaced by a forward header
#include "mozilla/ipc/Transport.h" // for Transport
// XXX Things that could be moved to ProtocolUtils.cpp
#include "base/process_util.h" // for CloseProcessHandle
#include "prenv.h" // for PR_GetEnv

View File

@ -1,37 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_Transport_h
#define mozilla_ipc_Transport_h 1
#include "base/process_util.h"
#include "chrome/common/ipc_channel.h"
#ifdef OS_POSIX
# include "mozilla/ipc/Transport_posix.h"
#elif OS_WIN
# include "mozilla/ipc/Transport_win.h"
#endif
#include "mozilla/UniquePtr.h"
namespace mozilla {
namespace ipc {
typedef IPC::Channel Transport;
nsresult CreateTransport(TransportDescriptor* aOne, TransportDescriptor* aTwo);
UniquePtr<Transport> OpenDescriptor(const TransportDescriptor& aTd,
Transport::Mode aMode);
TransportDescriptor DuplicateDescriptor(const TransportDescriptor& aTd);
void CloseDescriptor(const TransportDescriptor& aTd);
} // namespace ipc
} // namespace mozilla
#endif // mozilla_ipc_Transport_h

View File

@ -1,76 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <unistd.h>
#include <string>
#include "base/eintr_wrapper.h"
#include "mozilla/ipc/Endpoint.h"
#include "mozilla/ipc/Transport.h"
#include "mozilla/ipc/FileDescriptor.h"
#include "mozilla/ipc/ProtocolUtils.h"
using base::ProcessHandle;
namespace mozilla {
namespace ipc {
nsresult CreateTransport(TransportDescriptor* aOne, TransportDescriptor* aTwo) {
auto id = IPC::Channel::GenerateVerifiedChannelID();
// Use MODE_SERVER to force creation of the socketpair
Transport t(id, Transport::MODE_SERVER, nullptr);
int fd1 = t.GetFileDescriptor();
int fd2, dontcare;
t.GetClientFileDescriptorMapping(&fd2, &dontcare);
if (fd1 < 0 || fd2 < 0) {
return NS_ERROR_TRANSPORT_INIT;
}
// The Transport closes these fds when it goes out of scope, so we
// dup them here
fd1 = dup(fd1);
if (fd1 < 0) {
AnnotateCrashReportWithErrno(
CrashReporter::Annotation::IpcCreateTransportDupErrno, errno);
}
fd2 = dup(fd2);
if (fd2 < 0) {
AnnotateCrashReportWithErrno(
CrashReporter::Annotation::IpcCreateTransportDupErrno, errno);
}
if (fd1 < 0 || fd2 < 0) {
IGNORE_EINTR(close(fd1));
IGNORE_EINTR(close(fd2));
return NS_ERROR_DUPLICATE_HANDLE;
}
aOne->mFd = fd1;
aTwo->mFd = fd2;
return NS_OK;
}
UniquePtr<Transport> OpenDescriptor(const TransportDescriptor& aTd,
Transport::Mode aMode) {
return MakeUnique<Transport>(aTd.mFd, aMode, nullptr);
}
TransportDescriptor DuplicateDescriptor(const TransportDescriptor& aTd) {
TransportDescriptor result = aTd;
result.mFd = dup(aTd.mFd);
if (result.mFd == -1) {
AnnotateSystemError();
}
MOZ_RELEASE_ASSERT(result.mFd != -1, "DuplicateDescriptor failed");
return result;
}
void CloseDescriptor(const TransportDescriptor& aTd) { close(aTd.mFd); }
} // namespace ipc
} // namespace mozilla

View File

@ -1,43 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_Transport_posix_h
#define mozilla_ipc_Transport_posix_h 1
#include "ipc/IPCMessageUtils.h"
namespace mozilla {
namespace ipc {
struct TransportDescriptor {
int mFd;
};
} // namespace ipc
} // namespace mozilla
namespace IPC {
template <>
struct ParamTraits<mozilla::ipc::TransportDescriptor> {
typedef mozilla::ipc::TransportDescriptor paramType;
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, mozilla::UniqueFileHandle{aParam.mFd});
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
mozilla::UniqueFileHandle fd;
if (!ReadParam(aMsg, aIter, &fd)) {
return false;
}
aResult->mFd = fd.release();
return true;
}
};
} // namespace IPC
#endif // mozilla_ipc_Transport_posix_h

View File

@ -1,81 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "base/message_loop.h"
#include "mozilla/ipc/Transport.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include <windows.h>
using base::ProcessHandle;
namespace mozilla {
namespace ipc {
nsresult CreateTransport(TransportDescriptor* aOne, TransportDescriptor* aTwo) {
auto id = IPC::Channel::GenerateVerifiedChannelID();
// Use MODE_SERVER to force creation of the pipe
// NB: we create the server pipe immediately, instead of just
// grabbing an ID, on purpose. In the current setup, the client
// needs to connect to an existing server pipe, so to prevent race
// conditions, we create the server side here. When we send the pipe
// to the server, we DuplicateHandle it to the server process to give it
// access.
Transport t(id, Transport::MODE_SERVER, nullptr);
HANDLE serverPipe = t.GetServerPipeHandle();
if (!serverPipe) {
return NS_ERROR_TRANSPORT_INIT;
}
// Make a copy of the handle owned by the `Transport` which will be
// transferred to the actual server process.
if (!::DuplicateHandle(GetCurrentProcess(), serverPipe, GetCurrentProcess(),
&aOne->mServerPipeHandle, 0, false,
DUPLICATE_SAME_ACCESS)) {
return NS_ERROR_DUPLICATE_HANDLE;
}
aOne->mPipeName = aTwo->mPipeName = id;
aTwo->mServerPipeHandle = INVALID_HANDLE_VALUE;
return NS_OK;
}
UniquePtr<Transport> OpenDescriptor(const TransportDescriptor& aTd,
Transport::Mode aMode) {
return MakeUnique<Transport>(aTd.mPipeName, aTd.mServerPipeHandle, aMode,
nullptr);
}
TransportDescriptor DuplicateDescriptor(const TransportDescriptor& aTd) {
// We're duplicating this handle in our own process for bookkeeping purposes.
if (aTd.mServerPipeHandle == INVALID_HANDLE_VALUE) {
return aTd;
}
HANDLE serverDup;
bool ok = ::DuplicateHandle(GetCurrentProcess(), aTd.mServerPipeHandle,
GetCurrentProcess(), &serverDup, 0, false,
DUPLICATE_SAME_ACCESS);
if (!ok) {
AnnotateSystemError();
}
MOZ_RELEASE_ASSERT(ok);
TransportDescriptor desc = aTd;
desc.mServerPipeHandle = serverDup;
return desc;
}
void CloseDescriptor(const TransportDescriptor& aTd) {
// We're closing our own local copy of the pipe.
CloseHandle(aTd.mServerPipeHandle);
}
} // namespace ipc
} // namespace mozilla

View File

@ -1,61 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_Transport_win_h
#define mozilla_ipc_Transport_win_h 1
#include <string>
#include "base/process.h"
#include "ipc/IPCMessageUtils.h"
#include "nsWindowsHelpers.h"
#include "nsXULAppAPI.h"
#include "mozilla/UniquePtrExtensions.h"
namespace mozilla {
namespace ipc {
struct TransportDescriptor {
std::wstring mPipeName;
HANDLE mServerPipeHandle;
base::ProcessId mDestinationProcessId;
};
} // namespace ipc
} // namespace mozilla
namespace IPC {
template <>
struct ParamTraits<mozilla::ipc::TransportDescriptor> {
typedef mozilla::ipc::TransportDescriptor paramType;
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, aParam.mPipeName);
WriteParam(aMsg, mozilla::UniqueFileHandle(aParam.mServerPipeHandle));
WriteParam(aMsg, aParam.mDestinationProcessId);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
mozilla::UniqueFileHandle serverPipeHandle;
bool r = (ReadParam(aMsg, aIter, &aResult->mPipeName) &&
ReadParam(aMsg, aIter, &serverPipeHandle) &&
ReadParam(aMsg, aIter, &aResult->mDestinationProcessId));
if (!r) {
return r;
}
if (serverPipeHandle) {
aResult->mServerPipeHandle = serverPipeHandle.release();
} else {
aResult->mServerPipeHandle = INVALID_HANDLE_VALUE;
}
return true;
}
};
} // namespace IPC
#endif // mozilla_ipc_Transport_win_h

View File

@ -10,7 +10,6 @@ EXPORTS += [
]
EXPORTS.mozilla.ipc += [
"AutoTransportDescriptor.h",
"BackgroundChild.h",
"BackgroundParent.h",
"BackgroundStarterChild.h",
@ -63,7 +62,6 @@ EXPORTS.mozilla.ipc += [
"ShmemMessageUtils.h",
"TaintingIPCUtils.h",
"TaskFactory.h",
"Transport.h",
"TransportSecurityInfoUtils.h",
"URIUtils.h",
"UtilityProcessChild.h",
@ -76,21 +74,13 @@ EXPORTS.mozilla.ipc += [
]
if CONFIG["OS_ARCH"] == "WINNT":
EXPORTS.mozilla.ipc += [
"Transport_win.h",
]
SOURCES += [
"SharedMemory_windows.cpp",
"Transport_win.cpp",
"WindowsMessageLoop.cpp",
]
else:
EXPORTS.mozilla.ipc += [
"Transport_posix.h",
]
UNIFIED_SOURCES += [
"SharedMemory_posix.cpp",
"Transport_posix.cpp",
]
if CONFIG["OS_ARCH"] == "WINNT":
@ -163,7 +153,6 @@ EXPORTS.ipc += [
]
UNIFIED_SOURCES += [
"AutoTransportDescriptor.cpp",
"BackgroundImpl.cpp",
"BackgroundUtils.cpp",
"BrowserProcessSubThread.cpp",

View File

@ -1411,16 +1411,12 @@ class _DecorateWithCxxStuff(ipdl.ast.Visitor):
Typedef(Type("mozilla::ipc::ActorHandle"), "ActorHandle"),
Typedef(Type("base::ProcessId"), "ProcessId"),
Typedef(Type("mozilla::ipc::ProtocolId"), "ProtocolId"),
Typedef(Type("mozilla::ipc::Transport"), "Transport"),
Typedef(Type("mozilla::ipc::Endpoint"), "Endpoint", ["FooSide"]),
Typedef(
Type("mozilla::ipc::ManagedEndpoint"),
"ManagedEndpoint",
["FooSide"],
),
Typedef(
Type("mozilla::ipc::TransportDescriptor"), "TransportDescriptor"
),
Typedef(Type("mozilla::UniquePtr"), "UniquePtr", ["T"]),
Typedef(
Type("mozilla::ipc::ResponseRejectReason"), "ResponseRejectReason"