| // Copyright 2018 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // This file contains type and function definitions relevant to Mojo invitation |
| // APIs. |
| // |
| // Note: This header should be compilable as C. |
| |
| #ifndef MOJO_PUBLIC_C_SYSTEM_INVITATION_H_ |
| #define MOJO_PUBLIC_C_SYSTEM_INVITATION_H_ |
| |
| #include <stdint.h> |
| |
| #include "mojo/public/c/system/macros.h" |
| #include "mojo/public/c/system/platform_handle.h" |
| #include "mojo/public/c/system/system_export.h" |
| #include "mojo/public/c/system/types.h" |
| |
| // Flags included in |MojoProcessErrorDetails| indicating additional status |
| // information. |
| typedef uint32_t MojoProcessErrorFlags; |
| |
| // No flags. |
| #define MOJO_PROCESS_ERROR_FLAG_NONE ((MojoProcessErrorFlags)0) |
| |
| // If set, the process has been disconnected. No further |
| // |MojoProcessErrorHandler| invocations occur for it, and any IPC primitives |
| // (message pipes, data pipes) which were connected to it have been or will |
| // imminently be disconnected. |
| #define MOJO_PROCESS_ERROR_FLAG_DISCONNECTED ((MojoProcessErrorFlags)1) |
| |
| // Details regarding why an invited process has had its connection to this |
| // process terminated by the system. See |MojoProcessErrorHandler| and |
| // |MojoSendInvitation()|. |
| struct MOJO_ALIGNAS(8) MojoProcessErrorDetails { |
| // The size of this structure, used for versioning. |
| uint32_t struct_size; |
| |
| // The length of the string pointed to by |error_message| below. |
| uint32_t error_message_length; |
| |
| // An error message corresponding to the reason why the connection was |
| // terminated. This is an information message which may be useful to |
| // developers. |
| MOJO_POINTER_FIELD(const char*, error_message); |
| |
| // See |MojoProcessErrorFlags|. |
| MojoProcessErrorFlags flags; |
| }; |
| MOJO_STATIC_ASSERT(sizeof(struct MojoProcessErrorDetails) == 24, |
| "MojoProcessErrorDetails has wrong size."); |
| |
| // An opaque process handle value which must be provided when sending an |
| // invitation to another process via a platform transport. See |
| // |MojoSendInvitation()|. |
| struct MOJO_ALIGNAS(8) MojoPlatformProcessHandle { |
| // The size of this structure, used for versioning. |
| uint32_t struct_size; |
| |
| // The process handle value. For Windows this is a valid process HANDLE value. |
| // For Fuchsia it must be |zx_handle_t| process handle, and for all other |
| // POSIX systems, it's a PID. |
| uint64_t value; |
| }; |
| MOJO_STATIC_ASSERT(sizeof(struct MojoPlatformProcessHandle) == 16, |
| "MojoPlatformProcesHandle has wrong size."); |
| |
| // Enumeration indicating the type of transport over which an invitation will be |
| // sent or received. |
| typedef uint32_t MojoInvitationTransportType; |
| |
| // The channel transport type embodies common platform-specific OS primitives |
| // for FIFO message passing: |
| // - For Windows, this is a named pipe. |
| // - For Fuchsia, it's a channel. |
| // - For all other POSIX systems, it's a Unix domain socket pair. |
| // |
| // See |MojoInvitationTransportHandle| for details. |
| #define MOJO_INVITATION_TRANSPORT_TYPE_CHANNEL ((MojoInvitationTransportType)0) |
| |
| // Similar to CHANNEL transport, but used for an endpoint which requires an |
| // additional step to accept an inbound connection. This corresponds to a |
| // bound listening socket on POSIX, or named pipe server handle on Windows. |
| // |
| // The remote endpoint should establish a working connection to the server side |
| // and wrap the handle to that connection using a CHANNEL transport. |
| #define MOJO_INVITATION_TRANSPORT_TYPE_CHANNEL_SERVER \ |
| ((MojoInvitationTransportType)1) |
| |
| // A transport endpoint over which an invitation may be sent or received via |
| // |MojoSendInvitation()| or |MojoAcceptInvitation()| respectively. |
| struct MOJO_ALIGNAS(8) MojoInvitationTransportEndpoint { |
| // The size of this structure, used for versioning. |
| uint32_t struct_size; |
| |
| // The type of this transport endpoint. See |MojoInvitationTransportType|. |
| MojoInvitationTransportType type; |
| |
| // The number of platform handles in |platform_handles| below. |
| uint32_t num_platform_handles; |
| |
| // Platform handle(s) corresponding to the system object(s) backing this |
| // endpoint. The concrete type of the handle(s) depends on |type|. |
| // |
| // For |MOJO_INVITATION_TRANSPORT_TYPE_CHANNEL| endpoints: |
| // - On Windows, this is a single named pipe HANDLE |
| // - On Fuchsua, this is a single channel Fuchsia handle |
| // - On other POSIX systems, this is a single Unix domain socket file |
| // descriptor. |
| MOJO_POINTER_FIELD(const struct MojoPlatformHandle*, platform_handles); |
| }; |
| MOJO_STATIC_ASSERT(sizeof(struct MojoInvitationTransportEndpoint) == 24, |
| "MojoInvitationTransportEndpoint has wrong size."); |
| |
| // Flags passed to |MojoCreateInvitation()| via |MojoCreateInvitationOptions|. |
| typedef uint32_t MojoCreateInvitationFlags; |
| |
| // No flags. Default behavior. |
| #define MOJO_CREATE_INVITATION_FLAG_NONE ((MojoCreateInvitationFlags)0) |
| |
| // Options passed to |MojoCreateInvitation()|. |
| struct MOJO_ALIGNAS(8) MojoCreateInvitationOptions { |
| // The size of this structure, used for versioning. |
| uint32_t struct_size; |
| |
| // See |MojoCreateInvitationFlags|. |
| MojoCreateInvitationFlags flags; |
| }; |
| MOJO_STATIC_ASSERT(sizeof(struct MojoCreateInvitationOptions) == 8, |
| "MojoCreateInvitationOptions has wrong size"); |
| |
| // Flags passed to |MojoAttachMessagePipeToInvitation()| via |
| // |MojoAttachMessagePipeToInvitationOptions|. |
| typedef uint32_t MojoAttachMessagePipeToInvitationFlags; |
| |
| // No flags. Default behavior. |
| #define MOJO_ATTACH_MESSAGE_PIPE_TO_INVITATION_FLAG_NONE \ |
| ((MojoAttachMessagePipeToInvitationFlags)0) |
| |
| // Options passed to |MojoAttachMessagePipeToInvitation()|. |
| struct MOJO_ALIGNAS(8) MojoAttachMessagePipeToInvitationOptions { |
| // The size of this structure, used for versioning. |
| uint32_t struct_size; |
| |
| // See |MojoAttachMessagePipeToInvitationFlags|. |
| MojoAttachMessagePipeToInvitationFlags flags; |
| }; |
| MOJO_STATIC_ASSERT(sizeof(struct MojoAttachMessagePipeToInvitationOptions) == 8, |
| "MojoAttachMessagePipeToInvitationOptions has wrong size"); |
| |
| // Flags passed to |MojoExtractMessagePipeFromInvitation()| via |
| // |MojoExtractMessagePipeFromInvitationOptions|. |
| typedef uint32_t MojoExtractMessagePipeFromInvitationFlags; |
| |
| // No flags. Default behavior. |
| #define MOJO_EXTRACT_MESSAGE_PIPE_FROM_INVITATION_FLAG_NONE \ |
| ((MojoExtractMessagePipeFromInvitationFlags)0) |
| |
| // Options passed to |MojoExtractMessagePipeFromInvitation()|. |
| struct MOJO_ALIGNAS(8) MojoExtractMessagePipeFromInvitationOptions { |
| // The size of this structure, used for versioning. |
| uint32_t struct_size; |
| |
| // See |MojoExtractMessagePipeFromInvitationFlags|. |
| MojoExtractMessagePipeFromInvitationFlags flags; |
| }; |
| MOJO_STATIC_ASSERT( |
| sizeof(struct MojoExtractMessagePipeFromInvitationOptions) == 8, |
| "MojoExtractMessagePipeFromInvitationOptions has wrong size"); |
| |
| // Flags passed to |MojoSendInvitation()| via |MojoSendInvitationOptions|. |
| typedef uint32_t MojoSendInvitationFlags; |
| |
| // No flags. Default behavior. |
| #define MOJO_SEND_INVITATION_FLAG_NONE ((MojoSendInvitationFlags)0) |
| |
| // Send an isolated invitation to the receiver. Isolated invitations only |
| // establish communication between the sender and the receiver. Accepting an |
| // isolated invitation does not make IPC possible between the sender and any |
| // other members of the receiver's process graph, nor does it make IPC possible |
| // between the receiver and any other members of the sender's process graph. |
| // |
| // Invitations sent with this flag set must be accepted with the corresponding |
| // |MOJO_ACCEPT_INVITATION_FLAG_ISOLATED| flag set, and may only have a single |
| // message pipe attached with a name of exactly four zero-bytes ("\0\0\0\0"). |
| #define MOJO_SEND_INVITATION_FLAG_ISOLATED ((MojoSendInvitationFlags)1) |
| |
| // Options passed to |MojoSendInvitation()|. |
| struct MOJO_ALIGNAS(8) MojoSendInvitationOptions { |
| // The size of this structure, used for versioning. |
| uint32_t struct_size; |
| |
| // See |MojoSendInvitationFlags|. |
| MojoSendInvitationFlags flags; |
| |
| // If |flags| includes |MOJO_SEND_INVITATION_FLAG_ISOLATED| then these fields |
| // specify a name identifying the established isolated connection. There are |
| // no restrictions on the value given. If |isolated_connection_name_length| is |
| // non-zero, the system ensures that only one isolated process connection can |
| // exist for the given name at any time. |
| MOJO_POINTER_FIELD(const char*, isolated_connection_name); |
| uint32_t isolated_connection_name_length; |
| }; |
| MOJO_STATIC_ASSERT(sizeof(struct MojoSendInvitationOptions) == 24, |
| "MojoSendInvitationOptions has wrong size"); |
| |
| // Flags passed to |MojoAcceptInvitation()| via |MojoAcceptInvitationOptions|. |
| typedef uint32_t MojoAcceptInvitationFlags; |
| |
| // No flags. Default behavior. |
| #define MOJO_ACCEPT_INVITATION_FLAG_NONE ((MojoAcceptInvitationFlags)0) |
| |
| // Accept an isoalted invitation from the sender. See |
| // |MOJO_SEND_INVITATION_FLAG_ISOLATED| for details. |
| #define MOJO_ACCEPT_INVITATION_FLAG_ISOLATED ((MojoAcceptInvitationFlags)1) |
| |
| // Options passed to |MojoAcceptInvitation()|. |
| struct MOJO_ALIGNAS(8) MojoAcceptInvitationOptions { |
| // The size of this structure, used for versioning. |
| uint32_t struct_size; |
| |
| // See |MojoAcceptInvitationFlags|. |
| MojoAcceptInvitationFlags flags; |
| }; |
| MOJO_STATIC_ASSERT(sizeof(struct MojoAcceptInvitationOptions) == 8, |
| "MojoAcceptInvitationOptions has wrong size"); |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| // A callback which may be invoked by the system when a connection to an invited |
| // process is terminated due to a communication error (i.e. the invited process |
| // has sent a message which fails some validation check in the system). See |
| // |MojoSendInvitation()|. |
| // |
| // |context| is the value of |context| given to |MojoSendInvitation()| when |
| // inviting the process for whom this callback is being invoked. |
| typedef void (*MojoProcessErrorHandler)( |
| uintptr_t context, |
| const struct MojoProcessErrorDetails* details); |
| |
| // Creates a new invitation to be sent to another process. |
| // |
| // An invitation is used to invite another process to join this process's |
| // IPC network. The caller must already be a member of a Mojo network, either |
| // either by itself having been previously invited, or by being the Mojo broker |
| // process initialized via the Mojo Core Embedder API. |
| // |
| // Invitations can have message pipes attached to them, and these message pipes |
| // are used to bootstrap Mojo IPC between the inviter and the invitee. See |
| // |MojoAttachMessagePipeToInvitation()| for attaching message pipes, and |
| // |MojoSendInvitation()| for sending an invitation. |
| // |
| // |options| controls behavior. May be null for default behavior. |
| // |invitation_handle| must be the address of storage for a MojoHandle value |
| // to be output upon success. |
| // |
| // NOTE: If discarding an invitation instead of sending it with |
| // |MojoSendInvitation()|, you must close its handle (i.e. |MojoClose()|) to |
| // avoid leaking associated system resources. |
| // |
| // Returns: |
| // |MOJO_RESULT_OK| if the invitation was created successfully. The new |
| // invitation's handle is stored in |*invitation_handle| before returning. |
| // |MOJO_RESULT_INVALID_ARGUMENT| if |options| was non-null but malformed. |
| // |MOJO_RESULT_RESOURCE_EXHAUSTED| if a handle could not be allocated for the |
| // new invitation. |
| MOJO_SYSTEM_EXPORT MojoResult |
| MojoCreateInvitation(const struct MojoCreateInvitationOptions* options, |
| MojoHandle* invitation_handle); |
| |
| // Attaches a message pipe endpoint to an invitation. |
| // |
| // This creates a new message pipe which will span the boundary between the |
| // calling process and the invitation's eventual target process. One end of the |
| // new pipe is attached to the invitation while the other end is returned to the |
| // caller. Every attached message pipe has an arbitrary |name| value which |
| // identifies it within the invitation. |
| // |
| // Message pipes can be extracted by the recipient by calling |
| // |MojoExtractMessagePipeFromInvitation()|. It is up to applications to |
| // communicate out-of-band or establish a convention for how attached pipes |
| // are named. |
| // |
| // |invitation_handle| is the invitation to which a pipe should be attached. |
| // |name| is an arbitrary name to give this pipe, required to extract the pipe |
| // on the receiving end of the invitation. Note that the name is scoped to |
| // this invitation only, so e.g. multiple invitations may attach pipes with |
| // the name "foo", but any given invitation may only have a single pipe |
| // attached with that name. |
| // |name_num_bytes| is the number of bytes from |name| to use as the name. |
| // |options| controls behavior. May be null for default behavior. |
| // |message_pipe_handle| is the address of storage for a MojoHandle value. |
| // Upon success, the handle of the local endpoint of the new message pipe |
| // will be stored here. |
| // |
| // Returns: |
| // |MOJO_RESULT_OK| if the pipe was created and attached successfully. The |
| // local endpoint of the pipe has its handle stored in |
| // |*message_pipe_handle| before returning. The other endpoint is attached |
| // to the invitation. |
| // |MOJO_RESULT_INVALID_ARGUMENT| if |invitation_handle| was not an invitation |
| // handle, |options| was non-null but malformed, or |message_pipe_handle| |
| // was null. |
| // |MOJO_RESULT_ALREADY_EXISTS| if |name| was already in use for this |
| // invitation. |
| // |MOJO_RESULT_RESOURCE_EXHAUSTED| if a handle could not be allocated for the |
| // new local message pipe endpoint. |
| MOJO_SYSTEM_EXPORT MojoResult MojoAttachMessagePipeToInvitation( |
| MojoHandle invitation_handle, |
| const void* name, |
| uint32_t name_num_bytes, |
| const struct MojoAttachMessagePipeToInvitationOptions* options, |
| MojoHandle* message_pipe_handle); |
| |
| // Extracts a message pipe endpoint from an invitation. |
| // |
| // |invitation_handle| is the invitation from which to extract the endpoint. |
| // |name| is the name of the endpoint within the invitation. This corresponds |
| // to the name that was given to |MojoAttachMessagePipeToInvitation()| when |
| // the endpoint was attached. |
| // |name_num_bytes| is the number of bytes from |name| to use as the name. |
| // |options| controls behavior. May be null for default behavior. |
| // |message_pipe_handle| is the address of storage for a MojoHandle value. |
| // Upon success, the handle of the extracted message pipe endpoint will be |
| // stored here. |
| // |
| // Note that it is possible to extract an endpoint from an invitation even |
| // before the invitation has been sent to a remote process. If this is done and |
| // then the invitation is sent, the receiver will not see this endpoint as it |
| // will no longer be attached. |
| // |
| // Returns: |
| // |MOJO_RESULT_OK| if a new local message pipe endpoint was successfully |
| // created and returned in |*message_pipe_handle|. Note that the |
| // association of this endpoint with an invitation attachment is |
| // necessarily an asynchronous operation, and it is not known at return |
| // whether an attachment named |name| actually exists on the invitation. |
| // As such, the operation may still fail eventually, resuling in a broken |
| // pipe, i.e. the extracted pipe will signal peer closure. |
| // |MOJO_RESULT_INVALID_ARGUMENT| if |invitation_handle| was not an invitation |
| // handle, |options| was non-null but malformed, or |message_pipe_handle| |
| // was null. |
| // |MOJO_RESULT_RESOURCE_EXHAUSTED| if a handle could not be allocated for the |
| // new local message pipe endpoint. |
| // |MOJO_RESULT_NOT_FOUND| if it is known at call time that there is no pipe |
| // named |name| attached to the invitation. This is possible if the |
| // invtation was created within the calling process by |
| // |MojoCreateInvitation()|. |
| MOJO_SYSTEM_EXPORT MojoResult MojoExtractMessagePipeFromInvitation( |
| MojoHandle invitation_handle, |
| const void* name, |
| uint32_t name_num_bytes, |
| const struct MojoExtractMessagePipeFromInvitationOptions* options, |
| MojoHandle* message_pipe_handle); |
| |
| // Sends an invitation on a transport endpoint to bootstrap IPC between the |
| // calling process and another process. |
| // |
| // |invitation_handle| is the handle of the invitation to send. |
| // |process_handle| is an opaque, platform-specific handle to the remote |
| // process. See |MojoPlatformProcessHandle|. This is not necessarily |
| // required to be a valid process handle, but on some platforms (namely |
| // Windows and Mac) it's important if the invitation target will need to |
| // send or receive any kind of platform handles (including shared memory) |
| // over Mojo message pipes. |
| // |transport_endpoint| is one endpoint of a platform transport primitive, the |
| // other endpoint of which should be established within the process |
| // corresponding to |*process_handle|. See |MojoInvitationTransportEndpoint| |
| // for details. |
| // |error_handler| is a function to invoke if the connection to the invitee |
| // encounters any kind of error condition, e.g. a message validation failure |
| // reported by |MojoNotifyBadMessage()|, or permanent disconnection. See |
| // |MojoProcessErrorDetails| for more information. |
| // |error_handler_context| is an arbitrary value to be associated with this |
| // process invitation. This value is passed as the |context| argument to |
| // |error_handler| when invoked regarding this invitee. |
| // |options| controls behavior. May be null for default behavior. |
| // |
| // This assumes ownership of any platform handles in |transport_endpoint| if |
| // and only if returning |MOJO_RESULT_OK|. In that case, |invitation_handle| is |
| // also invalidated. |
| // |
| // NOTE: It's pointless to send an invitation without at least one message pipe |
| // attached, so it is considered an error to attempt to do so. |
| // |
| // Returns: |
| // |MOJO_RESULT_OK| if the invitation was successfully sent over the |
| // transport. |invitation_handle| is implicitly closed. Note that this |
| // does not guarantee that the invitation has been received by the target |
| // yet, or that it ever will be (e.g. the target process may terminate |
| // first or simply fail to accept the invitation). |
| // |MOJO_RESULT_INVALID_ARGUMENT| if |invitation_handle| was not an invitation |
| // handle, |transport_endpoint| was null or malformed, or |options| was |
| // non-null but malformed. |
| // |MOJO_RESULT_ABORTED| if the system failed to issue any necessary |
| // communication via |transport_endpoint|, possibly due to a configuration |
| // issue with the endpoint. The caller may attempt to correct this |
| // situation and call again. |
| // |MOJO_RESULT_FAILED_PRECONDITION| if there were no message pipes attached |
| // to the invitation. The caller may correct this situation and call |
| // again. |
| // |MOJO_RESULT_UNIMPLEMENTED| if the transport endpoint type is not supported |
| // by the system's version of Mojo. |
| MOJO_SYSTEM_EXPORT MojoResult MojoSendInvitation( |
| MojoHandle invitation_handle, |
| const struct MojoPlatformProcessHandle* process_handle, |
| const struct MojoInvitationTransportEndpoint* transport_endpoint, |
| MojoProcessErrorHandler error_handler, |
| uintptr_t error_handler_context, |
| const struct MojoSendInvitationOptions* options); |
| |
| // Accepts an invitation from a transport endpoint to complete IPC bootstrapping |
| // between the calling process and whoever sent the invitation from the other |
| // end of the transport. |
| // |
| // |transport_endpoint| is one endpoint of a platform transport primitive, the |
| // other endpoint of which should be established within a process |
| // who has sent or will send an invitation via that endpoint. See |
| // |MojoInvitationTransportEndpoint| for details. |
| // |options| controls behavior. May be null for default behavior. |
| // |invitation_handle| is the address of storage for a MojoHandle value. Upon |
| // success, the handle of the accepted invitation will be stored here. |
| // |
| // Once an invitation is accepted, message pipes endpoints may be extracted from |
| // it by calling |MojoExtractMessagePipeFromInvitation()|. |
| // |
| // Note that it is necessary to eventually close (i.e. |MojoClose()|) any |
| // accepted invitation handle in order to clean up any associated system |
| // resources. If an accepted invitation is closed while it still has message |
| // pipes attached (i.e. not exracted as above), those pipe endpoints are also |
| // closed. |
| // |
| // Returns: |
| // |MOJO_RESULT_OK| if the invitation was successfully accepted. The handle |
| // to the invitation is stored in |*invitation_handle| before returning. |
| // |MOJO_RESULT_INVALID_ARGUMENT| if |transport_endpoint| was null or |
| // malfored, |options| was non-null but malformed, or |invitation_handle| |
| // was null. |
| // |MOJO_RESULT_ABORTED| if the system failed to receive any communication via |
| // |transport_endpoint|, possibly due to some configuration error. The |
| // caller may attempt to correct this situation and call again. |
| // |MOJO_RESULT_UNIMPLEMENTED| if the transport endpoint type is not supported |
| // by the system's version of Mojo. |
| MOJO_SYSTEM_EXPORT MojoResult MojoAcceptInvitation( |
| const struct MojoInvitationTransportEndpoint* transport_endpoint, |
| const struct MojoAcceptInvitationOptions* options, |
| MojoHandle* invitation_handle); |
| |
| #ifdef __cplusplus |
| } // extern "C" |
| #endif |
| |
| #endif // MOJO_PUBLIC_C_SYSTEM_INVITATION_H_ |