ipc_message.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. // Copyright (c) 2012 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. #ifndef IPC_IPC_MESSAGE_H_
  5. #define IPC_IPC_MESSAGE_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <string>
  9. #include "base/gtest_prod_util.h"
  10. #include "base/memory/ref_counted.h"
  11. #include "base/pickle.h"
  12. #include "build/build_config.h"
  13. #include "ipc/ipc_buildflags.h"
  14. #include "ipc/ipc_message_support_export.h"
  15. namespace mojo {
  16. namespace internal {
  17. struct UnmappedNativeStructSerializerImpl;
  18. }
  19. } // namespace mojo
  20. namespace IPC {
  21. namespace internal {
  22. class ChannelReader;
  23. } // namespace internal
  24. //------------------------------------------------------------------------------
  25. struct LogData;
  26. class MessageAttachmentSet;
  27. class IPC_MESSAGE_SUPPORT_EXPORT Message : public base::Pickle {
  28. public:
  29. enum PriorityValue {
  30. PRIORITY_LOW = 1,
  31. PRIORITY_NORMAL,
  32. PRIORITY_HIGH
  33. };
  34. // Bit values used in the flags field.
  35. // Upper 24 bits of flags store a reference number, so this enum is limited to
  36. // 8 bits.
  37. enum {
  38. PRIORITY_MASK = 0x03, // Low 2 bits of store the priority value.
  39. SYNC_BIT = 0x04,
  40. REPLY_BIT = 0x08,
  41. REPLY_ERROR_BIT = 0x10,
  42. UNBLOCK_BIT = 0x20,
  43. PUMPING_MSGS_BIT = 0x40, // Deprecated.
  44. HAS_SENT_TIME_BIT = 0x80,
  45. };
  46. ~Message() override;
  47. Message();
  48. // Initialize a message with a user-defined type, priority value, and
  49. // destination WebView ID.
  50. Message(int32_t routing_id, uint32_t type, PriorityValue priority);
  51. // Initializes a message from a const block of data. The data is not copied;
  52. // instead the data is merely referenced by this message. Only const methods
  53. // should be used on the message when initialized this way.
  54. Message(const char* data, size_t data_len);
  55. Message(const Message& other);
  56. Message& operator=(const Message& other);
  57. bool IsValid() const { return header_size() == sizeof(Header) && header(); }
  58. PriorityValue priority() const {
  59. return static_cast<PriorityValue>(header()->flags & PRIORITY_MASK);
  60. }
  61. // True if this is a synchronous message.
  62. void set_sync() {
  63. header()->flags |= SYNC_BIT;
  64. }
  65. bool is_sync() const {
  66. return (header()->flags & SYNC_BIT) != 0;
  67. }
  68. // Set this on a reply to a synchronous message.
  69. void set_reply() {
  70. header()->flags |= REPLY_BIT;
  71. }
  72. bool is_reply() const {
  73. return (header()->flags & REPLY_BIT) != 0;
  74. }
  75. // Set this on a reply to a synchronous message to indicate that no receiver
  76. // was found.
  77. void set_reply_error() {
  78. header()->flags |= REPLY_ERROR_BIT;
  79. }
  80. bool is_reply_error() const {
  81. return (header()->flags & REPLY_ERROR_BIT) != 0;
  82. }
  83. // Normally when a receiver gets a message and they're blocked on a
  84. // synchronous message Send, they buffer a message. Setting this flag causes
  85. // the receiver to be unblocked and the message to be dispatched immediately.
  86. void set_unblock(bool unblock) {
  87. if (unblock) {
  88. header()->flags |= UNBLOCK_BIT;
  89. } else {
  90. header()->flags &= static_cast<uint32_t>(~UNBLOCK_BIT);
  91. }
  92. }
  93. bool should_unblock() const {
  94. return (header()->flags & UNBLOCK_BIT) != 0;
  95. }
  96. void set_dispatch_error() const {
  97. dispatch_error_ = true;
  98. }
  99. bool dispatch_error() const {
  100. return dispatch_error_;
  101. }
  102. uint32_t type() const {
  103. return header()->type;
  104. }
  105. int32_t routing_id() const {
  106. return header()->routing;
  107. }
  108. void set_routing_id(int32_t new_id) {
  109. header()->routing = new_id;
  110. }
  111. uint32_t flags() const {
  112. return header()->flags;
  113. }
  114. // Sets all the given header values. The message should be empty at this
  115. // call.
  116. void SetHeaderValues(int32_t routing, uint32_t type, uint32_t flags);
  117. template<class T, class S, class P>
  118. static bool Dispatch(const Message* msg, T* obj, S* sender, P* parameter,
  119. void (T::*func)()) {
  120. (obj->*func)();
  121. return true;
  122. }
  123. template<class T, class S, class P>
  124. static bool Dispatch(const Message* msg, T* obj, S* sender, P* parameter,
  125. void (T::*func)(P*)) {
  126. (obj->*func)(parameter);
  127. return true;
  128. }
  129. // Used for async messages with no parameters.
  130. static void Log(std::string* name, const Message* msg, std::string* l) {
  131. }
  132. // The static method FindNext() returns several pieces of information, which
  133. // are aggregated into an instance of this struct.
  134. struct IPC_MESSAGE_SUPPORT_EXPORT NextMessageInfo {
  135. NextMessageInfo();
  136. ~NextMessageInfo();
  137. // Total message size. Always valid if |message_found| is true.
  138. // If |message_found| is false but we could determine message size
  139. // from the header, this field is non-zero. Otherwise it's zero.
  140. size_t message_size;
  141. // Whether an entire message was found in the given memory range.
  142. bool message_found;
  143. // Only filled in if |message_found| is true.
  144. // The start address is passed into FindNext() by the caller, so isn't
  145. // repeated in this struct. The end address of the pickle should be used to
  146. // construct a base::Pickle.
  147. const char* pickle_end;
  148. // Only filled in if |message_found| is true.
  149. // The end address of the message should be used to determine the start
  150. // address of the next message.
  151. const char* message_end;
  152. };
  153. // |info| is an output parameter and must not be nullptr.
  154. static void FindNext(const char* range_start,
  155. const char* range_end,
  156. NextMessageInfo* info);
  157. // WriteAttachment appends |attachment| to the end of the set. It returns
  158. // false iff the set is full.
  159. bool WriteAttachment(
  160. scoped_refptr<base::Pickle::Attachment> attachment) override;
  161. // ReadAttachment parses an attachment given the parsing state |iter| and
  162. // writes it to |*attachment|. It returns true on success.
  163. bool ReadAttachment(
  164. base::PickleIterator* iter,
  165. scoped_refptr<base::Pickle::Attachment>* attachment) const override;
  166. // Returns true if there are any attachment in this message.
  167. bool HasAttachments() const override;
  168. #if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
  169. // Adds the outgoing time from Time::Now() at the end of the message and sets
  170. // a bit to indicate that it's been added.
  171. void set_sent_time(int64_t time);
  172. int64_t sent_time() const;
  173. void set_received_time(int64_t time) const;
  174. int64_t received_time() const { return received_time_; }
  175. void set_output_params(const std::string& op) const { output_params_ = op; }
  176. const std::string& output_params() const { return output_params_; }
  177. // The following four functions are needed so we can log sync messages with
  178. // delayed replies. We stick the log data from the sent message into the
  179. // reply message, so that when it's sent and we have the output parameters
  180. // we can log it. As such, we set a flag on the sent message to not log it.
  181. void set_sync_log_data(LogData* data) const { log_data_ = data; }
  182. LogData* sync_log_data() const { return log_data_; }
  183. void set_dont_log() const { dont_log_ = true; }
  184. bool dont_log() const { return dont_log_; }
  185. #endif
  186. protected:
  187. friend class Channel;
  188. friend class ChannelMojo;
  189. friend class ChannelNacl;
  190. friend class ChannelPosix;
  191. friend class ChannelWin;
  192. friend class internal::ChannelReader;
  193. friend class MessageReplyDeserializer;
  194. friend class SyncMessage;
  195. friend struct mojo::internal::UnmappedNativeStructSerializerImpl;
  196. #pragma pack(push, 4)
  197. struct Header : base::Pickle::Header {
  198. int32_t routing; // ID of the view that this message is destined for
  199. uint32_t type; // specifies the user-defined message type
  200. uint32_t flags; // specifies control flags for the message
  201. #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  202. uint16_t num_fds; // the number of descriptors included with this message
  203. uint16_t pad; // explicitly initialize this to appease valgrind
  204. #endif
  205. };
  206. #pragma pack(pop)
  207. Header* header() {
  208. return headerT<Header>();
  209. }
  210. const Header* header() const {
  211. return headerT<Header>();
  212. }
  213. void Init();
  214. // Used internally to support IPC::Listener::OnBadMessageReceived.
  215. mutable bool dispatch_error_;
  216. // The set of file descriptors associated with this message.
  217. scoped_refptr<MessageAttachmentSet> attachment_set_;
  218. // Ensure that a MessageAttachmentSet is allocated
  219. void EnsureMessageAttachmentSet();
  220. MessageAttachmentSet* attachment_set() {
  221. EnsureMessageAttachmentSet();
  222. return attachment_set_.get();
  223. }
  224. const MessageAttachmentSet* attachment_set() const {
  225. return attachment_set_.get();
  226. }
  227. #if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
  228. // Used for logging.
  229. mutable int64_t received_time_;
  230. mutable std::string output_params_;
  231. mutable LogData* log_data_;
  232. mutable bool dont_log_;
  233. #endif
  234. FRIEND_TEST_ALL_PREFIXES(IPCMessageTest, FindNext);
  235. FRIEND_TEST_ALL_PREFIXES(IPCMessageTest, FindNextOverflow);
  236. };
  237. //------------------------------------------------------------------------------
  238. } // namespace IPC
  239. enum SpecialRoutingIDs {
  240. // indicates that we don't have a routing ID yet.
  241. MSG_ROUTING_NONE = -2,
  242. // indicates a general message not sent to a particular tab.
  243. MSG_ROUTING_CONTROL = INT32_MAX,
  244. };
  245. #define IPC_REPLY_ID 0xFFFFFFF0 // Special message id for replies
  246. #define IPC_LOGGING_ID 0xFFFFFFF1 // Special message id for logging
  247. #endif // IPC_IPC_MESSAGE_H_