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