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