• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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