tree: 94f54dd77f953e85772b194ea15467cad8db3343 [path history] [tgz]
  1. BUILD.gn
  2. DEPS
  3. main.cc
  4. mojo_proxy_test.cc
  5. mojo_proxy_test.test-mojom
  6. node_proxy.cc
  7. node_proxy.h
  8. portal_proxy.cc
  9. portal_proxy.h
  10. README.md
  11. switches.cc
  12. switches.h
mojo/proxy/README.md

Mojo Proxy

The Mojo Proxy is a simple standalone service which can act as a bridge between a process using Mojo+ipcz and a process running only the legacy Mojo Core implementation. Currently the service is only supported on POSIX systems.

Usage

On POSIX systems, a host process normally sends an invitation to some other client or service (the “target” herein) via a Unix socket. The invitation has one or more pipe attachments associated with it. The target accepts this invitation from a peer socket and extracts its pipe attachments, thus bootstrapping Mojo IPC for the target:

mojo::ScopedMessagePipeHandle ConnectToTarget(
    mojo::PlatformChannelEndpoint endpoint) {
  mojo::OutgoingInvitation invitation;
  mojo::ScopedMessagePipeHandle pipe = invitation.AttachMessagePipe("pipe!");
  mojo::OutgoingInvitation::Send(std::move(invitation), {},
                                 std::move(endpoint));
  return pipe;
}

If the host process is running Mojo+ipcz but the target is not, the host can instead launch an instance of this proxy executable to act as an intermediary.

This will require the host to allocate an additional socket pair for communication with the proxy.

Also note the proxy should be launched from the host via fork+exec so that it can inherit the necessary file descriptors.

mojo::ScopedMessagePipeHandle ConnectToLegacyTarget(
    mojo::PlatformChannelEndpoint endpoint) {
  // Create a new channel for host<->proxy communication.
  mojo::PlatformChannel proxy_channel;

  // Somehow launch the `mojo_proxy` instance via fork+exec, inheriting the
  // two passed descriptors. `target_fd` must be identified by
  // `--legacy-client-fd=N` and `proxy_fd` must be identified by
  // `--host-ipcz-transport-fd=N` on the `mojo_proxy` command line.
  // The attachment name "pipe!" must be passed via `--attachment-name`.
  base::ScopedFD target_fd = endpoint.TakePlatformHandle().TakeFD();
  base::ScopedFD proxy_fd =
      proxy_channel.TakeRemoteEndpoint().TakePlatformHandle().TakeFD();
  LaunchProxy(std::move(target_fd), std::move(proxy_fd), "pipe!");

  // Otherwise invitation looks the same as before, except we're sending it
  // over a different endpoint which goes through the proxy.
  mojo::OutgoingInvitation invitation;
  mojo::ScopedMessagePipeHandle pipe = invitation.AttachMessagePipe("pipe!");
  mojo::OutgoingInvitation::Send(std::move(invitation), {},
                                 proxy_channel.TakeLocalEndpoint());
  return pipe;
}

For applications which attach multiple pipes to an invitation, only numeric pipe names are supported. They can be passed to the proxy using --numeric-attachment-names=0,1,2 instead of using --attachment-name.

Finally, if the host is not a broker process it must also pass --inherit-ipcz-broker to the proxy.