Home | History | Annotate | Download | only in system
      1 // Copyright 2018 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.
      4 
      5 // This file contains type and function definitions relevant to Mojo invitation
      6 // APIs.
      7 //
      8 // Note: This header should be compilable as C.
      9 
     10 #ifndef MOJO_PUBLIC_C_SYSTEM_INVITATION_H_
     11 #define MOJO_PUBLIC_C_SYSTEM_INVITATION_H_
     12 
     13 #include <stdint.h>
     14 
     15 #include "mojo/public/c/system/macros.h"
     16 #include "mojo/public/c/system/platform_handle.h"
     17 #include "mojo/public/c/system/system_export.h"
     18 #include "mojo/public/c/system/types.h"
     19 
     20 // Flags included in |MojoProcessErrorDetails| indicating additional status
     21 // information.
     22 typedef uint32_t MojoProcessErrorFlags;
     23 
     24 // No flags.
     25 #define MOJO_PROCESS_ERROR_FLAG_NONE ((MojoProcessErrorFlags)0)
     26 
     27 // If set, the process has been disconnected. No further
     28 // |MojoProcessErrorHandler| invocations occur for it, and any IPC primitives
     29 // (message pipes, data pipes) which were connected to it have been or will
     30 // imminently be disconnected.
     31 #define MOJO_PROCESS_ERROR_FLAG_DISCONNECTED ((MojoProcessErrorFlags)1)
     32 
     33 // Details regarding why an invited process has had its connection to this
     34 // process terminated by the system. See |MojoProcessErrorHandler| and
     35 // |MojoSendInvitation()|.
     36 struct MOJO_ALIGNAS(8) MojoProcessErrorDetails {
     37   // The size of this structure, used for versioning.
     38   uint32_t struct_size;
     39 
     40   // The length of the string pointed to by |error_message| below.
     41   uint32_t error_message_length;
     42 
     43   // An error message corresponding to the reason why the connection was
     44   // terminated. This is an information message which may be useful to
     45   // developers.
     46   MOJO_POINTER_FIELD(const char*, error_message);
     47 
     48   // See |MojoProcessErrorFlags|.
     49   MojoProcessErrorFlags flags;
     50 };
     51 MOJO_STATIC_ASSERT(sizeof(MojoProcessErrorDetails) == 24,
     52                    "MojoProcessErrorDetails has wrong size.");
     53 
     54 // An opaque process handle value which must be provided when sending an
     55 // invitation to another process via a platform transport. See
     56 // |MojoSendInvitation()|.
     57 struct MOJO_ALIGNAS(8) MojoPlatformProcessHandle {
     58   // The size of this structure, used for versioning.
     59   uint32_t struct_size;
     60 
     61   // The process handle value. For Windows this is a valid process HANDLE value.
     62   // For Fuchsia it must be |zx_handle_t| process handle, and for all other
     63   // POSIX systems, it's a PID.
     64   uint64_t value;
     65 };
     66 MOJO_STATIC_ASSERT(sizeof(MojoPlatformProcessHandle) == 16,
     67                    "MojoPlatformProcesHandle has wrong size.");
     68 
     69 // Enumeration indicating the type of transport over which an invitation will be
     70 // sent or received.
     71 typedef uint32_t MojoInvitationTransportType;
     72 
     73 // The channel transport type embodies common platform-specific OS primitives
     74 // for FIFO message passing:
     75 //   - For Windows, this is a named pipe.
     76 //   - For Fuchsia, it's a channel.
     77 //   - For all other POSIX systems, it's a Unix domain socket pair.
     78 //
     79 // See |MojoInvitationTransportHandle| for details.
     80 #define MOJO_INVITATION_TRANSPORT_TYPE_CHANNEL ((MojoInvitationTransportType)0)
     81 
     82 // Similar to CHANNEL transport, but used for an endpoint which requires an
     83 // additional step to accept an inbound connection. This corresponds to a
     84 // bound listening socket on POSIX, or named pipe server handle on Windows.
     85 //
     86 // The remote endpoint should establish a working connection to the server side
     87 // and wrap the handle to that connection using a CHANNEL transport.
     88 #define MOJO_INVITATION_TRANSPORT_TYPE_CHANNEL_SERVER \
     89   ((MojoInvitationTransportType)1)
     90 
     91 // A transport endpoint over which an invitation may be sent or received via
     92 // |MojoSendInvitation()| or |MojoAcceptInvitation()| respectively.
     93 struct MOJO_ALIGNAS(8) MojoInvitationTransportEndpoint {
     94   // The size of this structure, used for versioning.
     95   uint32_t struct_size;
     96 
     97   // The type of this transport endpoint. See |MojoInvitationTransportType|.
     98   MojoInvitationTransportType type;
     99 
    100   // The number of platform handles in |platform_handles| below.
    101   uint32_t num_platform_handles;
    102 
    103   // Platform handle(s) corresponding to the system object(s) backing this
    104   // endpoint. The concrete type of the handle(s) depends on |type|.
    105   //
    106   // For |MOJO_INVITATION_TRANSPORT_TYPE_CHANNEL| endpoints:
    107   //   - On Windows, this is a single named pipe HANDLE
    108   //   - On Fuchsua, this is a single channel Fuchsia handle
    109   //   - On other POSIX systems, this is a single Unix domain socket file
    110   //     descriptor.
    111   MOJO_POINTER_FIELD(const struct MojoPlatformHandle*, platform_handles);
    112 };
    113 MOJO_STATIC_ASSERT(sizeof(MojoInvitationTransportEndpoint) == 24,
    114                    "MojoInvitationTransportEndpoint has wrong size.");
    115 
    116 // Flags passed to |MojoCreateInvitation()| via |MojoCreateInvitationOptions|.
    117 typedef uint32_t MojoCreateInvitationFlags;
    118 
    119 // No flags. Default behavior.
    120 #define MOJO_CREATE_INVITATION_FLAG_NONE ((MojoCreateInvitationFlags)0)
    121 
    122 // Options passed to |MojoCreateInvitation()|.
    123 struct MOJO_ALIGNAS(8) MojoCreateInvitationOptions {
    124   // The size of this structure, used for versioning.
    125   uint32_t struct_size;
    126 
    127   // See |MojoCreateInvitationFlags|.
    128   MojoCreateInvitationFlags flags;
    129 };
    130 MOJO_STATIC_ASSERT(sizeof(MojoCreateInvitationOptions) == 8,
    131                    "MojoCreateInvitationOptions has wrong size");
    132 
    133 // Flags passed to |MojoAttachMessagePipeToInvitation()| via
    134 // |MojoAttachMessagePipeToInvitationOptions|.
    135 typedef uint32_t MojoAttachMessagePipeToInvitationFlags;
    136 
    137 // No flags. Default behavior.
    138 #define MOJO_ATTACH_MESSAGE_PIPE_TO_INVITATION_FLAG_NONE \
    139   ((MojoAttachMessagePipeToInvitationFlags)0)
    140 
    141 // Options passed to |MojoAttachMessagePipeToInvitation()|.
    142 struct MOJO_ALIGNAS(8) MojoAttachMessagePipeToInvitationOptions {
    143   // The size of this structure, used for versioning.
    144   uint32_t struct_size;
    145 
    146   // See |MojoAttachMessagePipeToInvitationFlags|.
    147   MojoAttachMessagePipeToInvitationFlags flags;
    148 };
    149 MOJO_STATIC_ASSERT(sizeof(MojoAttachMessagePipeToInvitationOptions) == 8,
    150                    "MojoAttachMessagePipeToInvitationOptions has wrong size");
    151 
    152 // Flags passed to |MojoExtractMessagePipeFromInvitation()| via
    153 // |MojoExtractMessagePipeFromInvitationOptions|.
    154 typedef uint32_t MojoExtractMessagePipeFromInvitationFlags;
    155 
    156 // No flags. Default behavior.
    157 #define MOJO_EXTRACT_MESSAGE_PIPE_FROM_INVITATION_FLAG_NONE \
    158   ((MojoExtractMessagePipeFromInvitationFlags)0)
    159 
    160 // Options passed to |MojoExtractMessagePipeFromInvitation()|.
    161 struct MOJO_ALIGNAS(8) MojoExtractMessagePipeFromInvitationOptions {
    162   // The size of this structure, used for versioning.
    163   uint32_t struct_size;
    164 
    165   // See |MojoExtractMessagePipeFromInvitationFlags|.
    166   MojoExtractMessagePipeFromInvitationFlags flags;
    167 };
    168 MOJO_STATIC_ASSERT(
    169     sizeof(MojoExtractMessagePipeFromInvitationOptions) == 8,
    170     "MojoExtractMessagePipeFromInvitationOptions has wrong size");
    171 
    172 // Flags passed to |MojoSendInvitation()| via |MojoSendInvitationOptions|.
    173 typedef uint32_t MojoSendInvitationFlags;
    174 
    175 // No flags. Default behavior.
    176 #define MOJO_SEND_INVITATION_FLAG_NONE ((MojoSendInvitationFlags)0)
    177 
    178 // Send an isolated invitation to the receiver. Isolated invitations only
    179 // establish communication between the sender and the receiver. Accepting an
    180 // isolated invitation does not make IPC possible between the sender and any
    181 // other members of the receiver's process graph, nor does it make IPC possible
    182 // between the receiver and any other members of the sender's process graph.
    183 //
    184 // Invitations sent with this flag set must be accepted with the corresponding
    185 // |MOJO_ACCEPT_INVITATION_FLAG_ISOLATED| flag set, and may only have a single
    186 // message pipe attached with a name of exactly four zero-bytes ("\0\0\0\0").
    187 #define MOJO_SEND_INVITATION_FLAG_ISOLATED ((MojoSendInvitationFlags)1)
    188 
    189 // Options passed to |MojoSendInvitation()|.
    190 struct MOJO_ALIGNAS(8) MojoSendInvitationOptions {
    191   // The size of this structure, used for versioning.
    192   uint32_t struct_size;
    193 
    194   // See |MojoSendInvitationFlags|.
    195   MojoSendInvitationFlags flags;
    196 
    197   // If |flags| includes |MOJO_SEND_INVITATION_FLAG_ISOLATED| then these fields
    198   // specify a name identifying the established isolated connection. There are
    199   // no restrictions on the value given. If |isolated_connection_name_length| is
    200   // non-zero, the system ensures that only one isolated process connection can
    201   // exist for the given name at any time.
    202   MOJO_POINTER_FIELD(const char*, isolated_connection_name);
    203   uint32_t isolated_connection_name_length;
    204 };
    205 MOJO_STATIC_ASSERT(sizeof(MojoSendInvitationOptions) == 24,
    206                    "MojoSendInvitationOptions has wrong size");
    207 
    208 // Flags passed to |MojoAcceptInvitation()| via |MojoAcceptInvitationOptions|.
    209 typedef uint32_t MojoAcceptInvitationFlags;
    210 
    211 // No flags. Default behavior.
    212 #define MOJO_ACCEPT_INVITATION_FLAG_NONE ((MojoAcceptInvitationFlags)0)
    213 
    214 // Accept an isoalted invitation from the sender. See
    215 // |MOJO_SEND_INVITATION_FLAG_ISOLATED| for details.
    216 #define MOJO_ACCEPT_INVITATION_FLAG_ISOLATED ((MojoAcceptInvitationFlags)1)
    217 
    218 // Options passed to |MojoAcceptInvitation()|.
    219 struct MOJO_ALIGNAS(8) MojoAcceptInvitationOptions {
    220   // The size of this structure, used for versioning.
    221   uint32_t struct_size;
    222 
    223   // See |MojoAcceptInvitationFlags|.
    224   MojoAcceptInvitationFlags flags;
    225 };
    226 MOJO_STATIC_ASSERT(sizeof(MojoAcceptInvitationOptions) == 8,
    227                    "MojoAcceptInvitationOptions has wrong size");
    228 
    229 #ifdef __cplusplus
    230 extern "C" {
    231 #endif
    232 
    233 // A callback which may be invoked by the system when a connection to an invited
    234 // process is terminated due to a communication error (i.e. the invited process
    235 // has sent a message which fails some validation check in the system). See
    236 // |MojoSendInvitation()|.
    237 //
    238 // |context| is the value of |context| given to |MojoSendInvitation()| when
    239 // inviting the process for whom this callback is being invoked.
    240 typedef void (*MojoProcessErrorHandler)(
    241     uintptr_t context,
    242     const struct MojoProcessErrorDetails* details);
    243 
    244 // Creates a new invitation to be sent to another process.
    245 //
    246 // An invitation is used to invite another process to join this process's
    247 // IPC network. The caller must already be a member of a Mojo network, either
    248 // either by itself having been previously invited, or by being the Mojo broker
    249 // process initialized via the Mojo Core Embedder API.
    250 //
    251 // Invitations can have message pipes attached to them, and these message pipes
    252 // are used to bootstrap Mojo IPC between the inviter and the invitee. See
    253 // |MojoAttachMessagePipeToInvitation()| for attaching message pipes, and
    254 // |MojoSendInvitation()| for sending an invitation.
    255 //
    256 // |options| controls behavior. May be null for default behavior.
    257 // |invitation_handle| must be the address of storage for a MojoHandle value
    258 //     to be output upon success.
    259 //
    260 // NOTE: If discarding an invitation instead of sending it with
    261 // |MojoSendInvitation()|, you must close its handle (i.e. |MojoClose()|) to
    262 // avoid leaking associated system resources.
    263 //
    264 // Returns:
    265 //   |MOJO_RESULT_OK| if the invitation was created successfully. The new
    266 //       invitation's handle is stored in |*invitation_handle| before returning.
    267 //   |MOJO_RESULT_INVALID_ARGUMENT| if |options| was non-null but malformed.
    268 //   |MOJO_RESULT_RESOURCE_EXHAUSTED| if a handle could not be allocated for the
    269 //       new invitation.
    270 MOJO_SYSTEM_EXPORT MojoResult
    271 MojoCreateInvitation(const struct MojoCreateInvitationOptions* options,
    272                      MojoHandle* invitation_handle);
    273 
    274 // Attaches a message pipe endpoint to an invitation.
    275 //
    276 // This creates a new message pipe which will span the boundary between the
    277 // calling process and the invitation's eventual target process. One end of the
    278 // new pipe is attached to the invitation while the other end is returned to the
    279 // caller. Every attached message pipe has an arbitrary |name| value which
    280 // identifies it within the invitation.
    281 //
    282 // Message pipes can be extracted by the recipient by calling
    283 // |MojoExtractMessagePipeFromInvitation()|. It is up to applications to
    284 // communicate out-of-band or establish a convention for how attached pipes
    285 // are named.
    286 //
    287 // |invitation_handle| is the invitation to which a pipe should be attached.
    288 // |name| is an arbitrary name to give this pipe, required to extract the pipe
    289 //     on the receiving end of the invitation. Note that the name is scoped to
    290 //     this invitation only, so e.g. multiple invitations may attach pipes with
    291 //     the name "foo", but any given invitation may only have a single pipe
    292 //     attached with that name.
    293 // |name_num_bytes| is the number of bytes from |name| to use as the name.
    294 // |options| controls behavior. May be null for default behavior.
    295 // |message_pipe_handle| is the address of storage for a MojoHandle value.
    296 //     Upon success, the handle of the local endpoint of the new message pipe
    297 //     will be stored here.
    298 //
    299 // Returns:
    300 //   |MOJO_RESULT_OK| if the pipe was created and attached successfully. The
    301 //       local endpoint of the pipe has its handle stored in
    302 //       |*message_pipe_handle| before returning. The other endpoint is attached
    303 //       to the invitation.
    304 //   |MOJO_RESULT_INVALID_ARGUMENT| if |invitation_handle| was not an invitation
    305 //       handle, |options| was non-null but malformed, or |message_pipe_handle|
    306 //       was null.
    307 //   |MOJO_RESULT_ALREADY_EXISTS| if |name| was already in use for this
    308 //       invitation.
    309 //   |MOJO_RESULT_RESOURCE_EXHAUSTED| if a handle could not be allocated for the
    310 //       new local message pipe endpoint.
    311 MOJO_SYSTEM_EXPORT MojoResult MojoAttachMessagePipeToInvitation(
    312     MojoHandle invitation_handle,
    313     const void* name,
    314     uint32_t name_num_bytes,
    315     const struct MojoAttachMessagePipeToInvitationOptions* options,
    316     MojoHandle* message_pipe_handle);
    317 
    318 // Extracts a message pipe endpoint from an invitation.
    319 //
    320 // |invitation_handle| is the invitation from which to extract the endpoint.
    321 // |name| is the name of the endpoint within the invitation. This corresponds
    322 //     to the name that was given to |MojoAttachMessagePipeToInvitation()| when
    323 //     the endpoint was attached.
    324 // |name_num_bytes| is the number of bytes from |name| to use as the name.
    325 // |options| controls behavior. May be null for default behavior.
    326 // |message_pipe_handle| is the address of storage for a MojoHandle value.
    327 //     Upon success, the handle of the extracted message pipe endpoint will be
    328 //     stored here.
    329 //
    330 // Note that it is possible to extract an endpoint from an invitation even
    331 // before the invitation has been sent to a remote process. If this is done and
    332 // then the invitation is sent, the receiver will not see this endpoint as it
    333 // will no longer be attached.
    334 //
    335 // Returns:
    336 //   |MOJO_RESULT_OK| if a new local message pipe endpoint was successfully
    337 //       created and returned in |*message_pipe_handle|. Note that the
    338 //       association of this endpoint with an invitation attachment is
    339 //       necessarily an asynchronous operation, and it is not known at return
    340 //       whether an attachment named |name| actually exists on the invitation.
    341 //       As such, the operation may still fail eventually, resuling in a broken
    342 //       pipe, i.e. the extracted pipe will signal peer closure.
    343 //   |MOJO_RESULT_INVALID_ARGUMENT| if |invitation_handle| was not an invitation
    344 //       handle, |options| was non-null but malformed, or |message_pipe_handle|
    345 //       was null.
    346 //   |MOJO_RESULT_RESOURCE_EXHAUSTED| if a handle could not be allocated for the
    347 //       new local message pipe endpoint.
    348 //   |MOJO_RESULT_NOT_FOUND| if it is known at call time that there is no pipe
    349 //       named |name| attached to the invitation. This is possible if the
    350 //       invtation was created within the calling process by
    351 //       |MojoCreateInvitation()|.
    352 MOJO_SYSTEM_EXPORT MojoResult MojoExtractMessagePipeFromInvitation(
    353     MojoHandle invitation_handle,
    354     const void* name,
    355     uint32_t name_num_bytes,
    356     const struct MojoExtractMessagePipeFromInvitationOptions* options,
    357     MojoHandle* message_pipe_handle);
    358 
    359 // Sends an invitation on a transport endpoint to bootstrap IPC between the
    360 // calling process and another process.
    361 //
    362 // |invitation_handle| is the handle of the invitation to send.
    363 // |process_handle| is an opaque, platform-specific handle to the remote
    364 //     process. See |MojoPlatformProcessHandle|. This is not necessarily
    365 //     required to be a valid process handle, but on some platforms (namely
    366 //     Windows and Mac) it's important if the invitation target will need to
    367 //     send or receive any kind of platform handles (including shared memory)
    368 //     over Mojo message pipes.
    369 // |transport_endpoint| is one endpoint of a platform transport primitive, the
    370 //     other endpoint of which should be established within the process
    371 //     corresponding to |*process_handle|. See |MojoInvitationTransportEndpoint|
    372 //     for details.
    373 // |error_handler| is a function to invoke if the connection to the invitee
    374 //     encounters any kind of error condition, e.g. a message validation failure
    375 //     reported by |MojoNotifyBadMessage()|, or permanent disconnection. See
    376 //     |MojoProcessErrorDetails| for more information.
    377 // |error_handler_context| is an arbitrary value to be associated with this
    378 //     process invitation. This value is passed as the |context| argument to
    379 //     |error_handler| when invoked regarding this invitee.
    380 // |options| controls behavior. May be null for default behavior.
    381 //
    382 // This assumes ownership of any platform handles in |transport_endpoint| if
    383 // and only if returning |MOJO_RESULT_OK|. In that case, |invitation_handle| is
    384 // also invalidated.
    385 //
    386 // NOTE: It's pointless to send an invitation without at least one message pipe
    387 // attached, so it is considered an error to attempt to do so.
    388 //
    389 // Returns:
    390 //   |MOJO_RESULT_OK| if the invitation was successfully sent over the
    391 //       transport. |invitation_handle| is implicitly closed. Note that this
    392 //       does not guarantee that the invitation has been received by the target
    393 //       yet, or that it ever will be (e.g. the target process may terminate
    394 //       first or simply fail to accept the invitation).
    395 //   |MOJO_RESULT_INVALID_ARGUMENT| if |invitation_handle| was not an invitation
    396 //       handle, |transport_endpoint| was null or malformed, or |options| was
    397 //       non-null but malformed.
    398 //   |MOJO_RESULT_ABORTED| if the system failed to issue any necessary
    399 //       communication via |transport_endpoint|, possibly due to a configuration
    400 //       issue with the endpoint. The caller may attempt to correct this
    401 //       situation and call again.
    402 //   |MOJO_RESULT_FAILED_PRECONDITION| if there were no message pipes attached
    403 //       to the invitation. The caller may correct this situation and call
    404 //       again.
    405 //   |MOJO_RESULT_UNIMPLEMENTED| if the transport endpoint type is not supported
    406 //       by the system's version of Mojo.
    407 MOJO_SYSTEM_EXPORT MojoResult MojoSendInvitation(
    408     MojoHandle invitation_handle,
    409     const struct MojoPlatformProcessHandle* process_handle,
    410     const struct MojoInvitationTransportEndpoint* transport_endpoint,
    411     MojoProcessErrorHandler error_handler,
    412     uintptr_t error_handler_context,
    413     const struct MojoSendInvitationOptions* options);
    414 
    415 // Accepts an invitation from a transport endpoint to complete IPC bootstrapping
    416 // between the calling process and whoever sent the invitation from the other
    417 // end of the transport.
    418 //
    419 // |transport_endpoint| is one endpoint of a platform transport primitive, the
    420 //     other endpoint of which should be established within a process
    421 //     who has sent or will send an invitation via that endpoint. See
    422 //     |MojoInvitationTransportEndpoint| for details.
    423 // |options| controls behavior. May be null for default behavior.
    424 // |invitation_handle| is the address of storage for a MojoHandle value. Upon
    425 //     success, the handle of the accepted invitation will be stored here.
    426 //
    427 // Once an invitation is accepted, message pipes endpoints may be extracted from
    428 // it by calling |MojoExtractMessagePipeFromInvitation()|.
    429 //
    430 // Note that it is necessary to eventually close (i.e. |MojoClose()|) any
    431 // accepted invitation handle in order to clean up any associated system
    432 // resources. If an accepted invitation is closed while it still has message
    433 // pipes attached (i.e. not exracted as above), those pipe endpoints are also
    434 // closed.
    435 //
    436 // Returns:
    437 //   |MOJO_RESULT_OK| if the invitation was successfully accepted. The handle
    438 //       to the invitation is stored in |*invitation_handle| before returning.
    439 //   |MOJO_RESULT_INVALID_ARGUMENT| if |transport_endpoint| was null or
    440 //       malfored, |options| was non-null but malformed, or |invitation_handle|
    441 //       was null.
    442 //   |MOJO_RESULT_ABORTED| if the system failed to receive any communication via
    443 //       |transport_endpoint|, possibly due to some configuration error. The
    444 //       caller may attempt to correct this situation and call again.
    445 //   |MOJO_RESULT_UNIMPLEMENTED| if the transport endpoint type is not supported
    446 //       by the system's version of Mojo.
    447 MOJO_SYSTEM_EXPORT MojoResult MojoAcceptInvitation(
    448     const struct MojoInvitationTransportEndpoint* transport_endpoint,
    449     const struct MojoAcceptInvitationOptions* options,
    450     MojoHandle* invitation_handle);
    451 
    452 #ifdef __cplusplus
    453 }  // extern "C"
    454 #endif
    455 
    456 #endif  // MOJO_PUBLIC_C_SYSTEM_INVITATION_H_
    457