Home | History | Annotate | Download | only in bindings
      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.
     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 
    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:
    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:
    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:
    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 
    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 //
    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