1 // Copyright 2014 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 #ifndef MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_
7
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <limits>
12 #include <memory>
13 #include <string>
14 #include <vector>
15
16 #include "base/callback.h"
17 #include "base/compiler_specific.h"
18 #include "base/component_export.h"
19 #include "base/logging.h"
20 #include "base/memory/ptr_util.h"
21 #include "mojo/public/cpp/bindings/lib/buffer.h"
22 #include "mojo/public/cpp/bindings/lib/message_internal.h"
23 #include "mojo/public/cpp/bindings/lib/unserialized_message_context.h"
24 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
25 #include "mojo/public/cpp/system/message.h"
26
27 namespace mojo {
28
29 class AssociatedGroupController;
30
31 using ReportBadMessageCallback =
32 base::OnceCallback<void(const std::string& error)>;
33
34 // Message is a holder for the data and handles to be sent over a MessagePipe.
35 // Message owns its data and handles, but a consumer of Message is free to
36 // mutate the data and handles. The message's data is comprised of a header
37 // followed by payload.
COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE)38 class COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) Message {
39 public:
40 static const uint32_t kFlagExpectsResponse = 1 << 0;
41 static const uint32_t kFlagIsResponse = 1 << 1;
42 static const uint32_t kFlagIsSync = 1 << 2;
43
44 // Constructs an uninitialized Message object.
45 Message();
46
47 // See the move-assignment operator below.
48 Message(Message&& other);
49
50 // Constructs a new message with an unserialized context attached. This
51 // message may be serialized later if necessary.
52 explicit Message(
53 std::unique_ptr<internal::UnserializedMessageContext> context);
54
55 // Constructs a new serialized Message object with optional handles attached.
56 // This message is fully functional and may be exchanged for a
57 // ScopedMessageHandle for transit over a message pipe. See TakeMojoMessage().
58 //
59 // If |handles| is non-null, any handles in |*handles| are attached to the
60 // newly constructed message.
61 //
62 // Note that |payload_size| is only the initially known size of the message
63 // payload, if any. The payload can be expanded after construction using the
64 // interface returned by |payload_buffer()|.
65 Message(uint32_t name,
66 uint32_t flags,
67 size_t payload_size,
68 size_t payload_interface_id_count,
69 std::vector<ScopedHandle>* handles);
70
71 // Constructs a new serialized Message object from an existing
72 // ScopedMessageHandle; e.g., one read from a message pipe.
73 //
74 // If the message had any handles attached, they will be extracted and
75 // retrievable via |handles()|. Such messages may NOT be sent back over
76 // another message pipe, but are otherwise safe to inspect and pass around.
77 Message(ScopedMessageHandle handle);
78
79 ~Message();
80
81 // Moves |other| into a new Message object. The moved-from Message becomes
82 // invalid and is effectively in a default-constructed state after this call.
83 Message& operator=(Message&& other);
84
85 // Resets the Message to an uninitialized state. Upon reset, the Message
86 // exists as if it were default-constructed: it has no data buffer and owns no
87 // handles.
88 void Reset();
89
90 // Indicates whether this Message is uninitialized.
91 bool IsNull() const { return !handle_.is_valid(); }
92
93 // Indicates whether this Message is serialized.
94 bool is_serialized() const { return serialized_; }
95
96 // Access the raw bytes of the message.
97 const uint8_t* data() const {
98 DCHECK(payload_buffer_.is_valid());
99 return static_cast<const uint8_t*>(payload_buffer_.data());
100 }
101 uint8_t* mutable_data() { return const_cast<uint8_t*>(data()); }
102
103 size_t data_num_bytes() const {
104 DCHECK(payload_buffer_.is_valid());
105 return payload_buffer_.cursor();
106 }
107
108 // Access the header.
109 const internal::MessageHeader* header() const {
110 return reinterpret_cast<const internal::MessageHeader*>(data());
111 }
112 internal::MessageHeader* header() {
113 return reinterpret_cast<internal::MessageHeader*>(mutable_data());
114 }
115
116 const internal::MessageHeaderV1* header_v1() const {
117 DCHECK_GE(version(), 1u);
118 return reinterpret_cast<const internal::MessageHeaderV1*>(data());
119 }
120 internal::MessageHeaderV1* header_v1() {
121 DCHECK_GE(version(), 1u);
122 return reinterpret_cast<internal::MessageHeaderV1*>(mutable_data());
123 }
124
125 const internal::MessageHeaderV2* header_v2() const {
126 DCHECK_GE(version(), 2u);
127 return reinterpret_cast<const internal::MessageHeaderV2*>(data());
128 }
129 internal::MessageHeaderV2* header_v2() {
130 DCHECK_GE(version(), 2u);
131 return reinterpret_cast<internal::MessageHeaderV2*>(mutable_data());
132 }
133
134 uint32_t version() const { return header()->version; }
135
136 uint32_t interface_id() const { return header()->interface_id; }
137 void set_interface_id(uint32_t id) { header()->interface_id = id; }
138
139 uint32_t name() const { return header()->name; }
140 bool has_flag(uint32_t flag) const { return !!(header()->flags & flag); }
141
142 // Access the request_id field (if present).
143 uint64_t request_id() const { return header_v1()->request_id; }
144 void set_request_id(uint64_t request_id) {
145 header_v1()->request_id = request_id;
146 }
147
148 // Access the payload.
149 const uint8_t* payload() const;
150 uint8_t* mutable_payload() { return const_cast<uint8_t*>(payload()); }
151 uint32_t payload_num_bytes() const;
152
153 uint32_t payload_num_interface_ids() const;
154 const uint32_t* payload_interface_ids() const;
155
156 internal::Buffer* payload_buffer() { return &payload_buffer_; }
157
158 // Access the handles of a received message. Note that these are unused on
159 // outgoing messages.
160 const std::vector<ScopedHandle>* handles() const { return &handles_; }
161 std::vector<ScopedHandle>* mutable_handles() { return &handles_; }
162
163 const std::vector<ScopedInterfaceEndpointHandle>*
164 associated_endpoint_handles() const {
165 return &associated_endpoint_handles_;
166 }
167 std::vector<ScopedInterfaceEndpointHandle>*
168 mutable_associated_endpoint_handles() {
169 return &associated_endpoint_handles_;
170 }
171
172 // Takes ownership of any handles within |*context| and attaches them to this
173 // Message.
174 void AttachHandlesFromSerializationContext(
175 internal::SerializationContext* context);
176
177 // Takes a scoped MessageHandle which may be passed to |WriteMessageNew()| for
178 // transmission. Note that this invalidates this Message object, taking
179 // ownership of its internal storage and any attached handles.
180 ScopedMessageHandle TakeMojoMessage();
181
182 // Notifies the system that this message is "bad," in this case meaning it was
183 // rejected by bindings validation code.
184 void NotifyBadMessage(const std::string& error);
185
186 // Serializes |associated_endpoint_handles_| into the payload_interface_ids
187 // field.
188 void SerializeAssociatedEndpointHandles(
189 AssociatedGroupController* group_controller);
190
191 // Deserializes |associated_endpoint_handles_| from the payload_interface_ids
192 // field.
193 bool DeserializeAssociatedEndpointHandles(
194 AssociatedGroupController* group_controller);
195
196 // If this Message has an unserialized message context attached, force it to
197 // be serialized immediately. Otherwise this does nothing.
198 void SerializeIfNecessary();
199
200 // Takes the unserialized message context from this Message if its tag matches
201 // |tag|.
202 std::unique_ptr<internal::UnserializedMessageContext> TakeUnserializedContext(
203 const internal::UnserializedMessageContext::Tag* tag);
204
205 template <typename MessageType>
206 std::unique_ptr<MessageType> TakeUnserializedContext() {
207 auto generic_context = TakeUnserializedContext(&MessageType::kMessageTag);
208 if (!generic_context)
209 return nullptr;
210 return base::WrapUnique(
211 generic_context.release()->template SafeCast<MessageType>());
212 }
213
214 #if defined(ENABLE_IPC_FUZZER)
215 const char* interface_name() const { return interface_name_; }
216 void set_interface_name(const char* interface_name) {
217 interface_name_ = interface_name;
218 }
219
220 const char* method_name() const { return method_name_; }
221 void set_method_name(const char* method_name) { method_name_ = method_name; }
222 #endif
223
224 private:
225 ScopedMessageHandle handle_;
226
227 // A Buffer which may be used to allocate blocks of data within the message
228 // payload for reading or writing.
229 internal::Buffer payload_buffer_;
230
231 std::vector<ScopedHandle> handles_;
232 std::vector<ScopedInterfaceEndpointHandle> associated_endpoint_handles_;
233
234 // Indicates whether this Message object is transferable, i.e. can be sent
235 // elsewhere. In general this is true unless |handle_| is invalid or
236 // serialized handles have been extracted from the serialized message object
237 // identified by |handle_|.
238 bool transferable_ = false;
239
240 // Indicates whether this Message object is serialized.
241 bool serialized_ = false;
242
243 #if defined(ENABLE_IPC_FUZZER)
244 const char* interface_name_ = nullptr;
245 const char* method_name_ = nullptr;
246 #endif
247
248 DISALLOW_COPY_AND_ASSIGN(Message);
249 };
250
COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE)251 class COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) MessageReceiver {
252 public:
253 virtual ~MessageReceiver() {}
254
255 // Indicates whether the receiver prefers to receive serialized messages.
256 virtual bool PrefersSerializedMessages();
257
258 // The receiver may mutate the given message. Returns true if the message
259 // was accepted and false otherwise, indicating that the message was invalid
260 // or malformed.
261 virtual bool Accept(Message* message) WARN_UNUSED_RESULT = 0;
262 };
263
264 class MessageReceiverWithResponder : public MessageReceiver {
265 public:
~MessageReceiverWithResponder()266 ~MessageReceiverWithResponder() override {}
267
268 // A variant on Accept that registers a MessageReceiver (known as the
269 // responder) to handle the response message generated from the given
270 // message. The responder's Accept method may be called during
271 // AcceptWithResponder or some time after its return.
272 virtual bool AcceptWithResponder(Message* message,
273 std::unique_ptr<MessageReceiver> responder)
274 WARN_UNUSED_RESULT = 0;
275 };
276
277 // A MessageReceiver that is also able to provide status about the state
278 // of the underlying MessagePipe to which it will be forwarding messages
279 // received via the |Accept()| call.
280 class MessageReceiverWithStatus : public MessageReceiver {
281 public:
~MessageReceiverWithStatus()282 ~MessageReceiverWithStatus() override {}
283
284 // Returns |true| if this MessageReceiver is currently bound to a MessagePipe,
285 // the pipe has not been closed, and the pipe has not encountered an error.
286 virtual bool IsConnected() = 0;
287
288 // Determines if this MessageReceiver is still bound to a message pipe and has
289 // not encountered any errors. This is asynchronous but may be called from any
290 // sequence. |callback| is eventually invoked from an arbitrary sequence with
291 // the result of the query.
292 virtual void IsConnectedAsync(base::OnceCallback<void(bool)> callback) = 0;
293 };
294
295 // An alternative to MessageReceiverWithResponder for cases in which it
296 // is necessary for the implementor of this interface to know about the status
297 // of the MessagePipe which will carry the responses.
298 class MessageReceiverWithResponderStatus : public MessageReceiver {
299 public:
~MessageReceiverWithResponderStatus()300 ~MessageReceiverWithResponderStatus() override {}
301
302 // A variant on Accept that registers a MessageReceiverWithStatus (known as
303 // the responder) to handle the response message generated from the given
304 // message. Any of the responder's methods (Accept or IsValid) may be called
305 // during AcceptWithResponder or some time after its return.
306 virtual bool AcceptWithResponder(Message* message,
307 std::unique_ptr<MessageReceiverWithStatus>
308 responder) WARN_UNUSED_RESULT = 0;
309 };
310
COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE)311 class COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) PassThroughFilter
312 : public MessageReceiver {
313 public:
314 PassThroughFilter();
315 ~PassThroughFilter() override;
316
317 // MessageReceiver:
318 bool Accept(Message* message) override;
319
320 private:
321 DISALLOW_COPY_AND_ASSIGN(PassThroughFilter);
322 };
323
324 namespace internal {
325 class SyncMessageResponseSetup;
326 }
327
328 // An object which should be constructed on the stack immediately before making
329 // a sync request for which the caller wishes to perform custom validation of
330 // the response value(s). It is illegal to make more than one sync call during
331 // the lifetime of the topmost SyncMessageResponseContext, but it is legal to
332 // nest contexts to support reentrancy.
333 //
334 // Usage should look something like:
335 //
336 // SyncMessageResponseContext response_context;
337 // foo_interface->SomeSyncCall(&response_value);
338 // if (response_value.IsBad())
339 // response_context.ReportBadMessage("Bad response_value!");
340 //
COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE)341 class COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) SyncMessageResponseContext {
342 public:
343 SyncMessageResponseContext();
344 ~SyncMessageResponseContext();
345
346 static SyncMessageResponseContext* current();
347
348 void ReportBadMessage(const std::string& error);
349
350 ReportBadMessageCallback GetBadMessageCallback();
351
352 private:
353 friend class internal::SyncMessageResponseSetup;
354
355 SyncMessageResponseContext* outer_context_;
356 Message response_;
357
358 DISALLOW_COPY_AND_ASSIGN(SyncMessageResponseContext);
359 };
360
361 // Read a single message from the pipe. The caller should have created the
362 // Message, but not called Initialize(). Returns MOJO_RESULT_SHOULD_WAIT if
363 // the caller should wait on the handle to become readable. Returns
364 // MOJO_RESULT_OK if the message was read successfully and should be
365 // dispatched, otherwise returns an error code if something went wrong.
366 //
367 // NOTE: The message hasn't been validated and may be malformed!
368 COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE)
369 MojoResult ReadMessage(MessagePipeHandle handle, Message* message);
370
371 // Reports the currently dispatching Message as bad. Note that this is only
372 // legal to call from directly within the stack frame of a message dispatch. If
373 // you need to do asynchronous work before you can determine the legitimacy of
374 // a message, use GetBadMessageCallback() and retain its result until you're
375 // ready to invoke or discard it.
376 COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE)
377 void ReportBadMessage(const std::string& error);
378
379 // Acquires a callback which may be run to report the currently dispatching
380 // Message as bad. Note that this is only legal to call from directly within the
381 // stack frame of a message dispatch, but the returned callback may be called
382 // exactly once any time thereafter to report the message as bad. This may only
383 // be called once per message.
384 COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE)
385 ReportBadMessageCallback GetBadMessageCallback();
386
387 } // namespace mojo
388
389 #endif // MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_
390