blob: 1023729316877c304e0169ef30cbd0817e6cf2c1 [file] [log] [blame]
[email protected]ce208f872012-03-07 20:42:561// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]946d1b22009-07-22 23:57:215#include "ipc/ipc_message.h"
initial.commit09911bf2008-07-26 23:55:296
erikchen29e0f2f2015-09-11 19:08:537#include <limits.h>
avi246998d82015-12-22 02:39:048#include <stddef.h>
9#include <stdint.h>
erikchen29e0f2f2015-09-11 19:08:5310
[email protected]dc4fa482014-02-25 15:30:1511#include "base/atomic_sequence_num.h"
initial.commit09911bf2008-07-26 23:55:2912#include "base/logging.h"
[email protected]526776c2009-02-07 00:39:2613#include "build/build_config.h"
morrita1aa788c2015-01-31 05:45:4214#include "ipc/ipc_message_attachment.h"
morrita4b5c28e22015-01-14 21:17:0615#include "ipc/ipc_message_attachment_set.h"
initial.commit09911bf2008-07-26 23:55:2916
[email protected]7135bb042009-02-12 04:05:2817#if defined(OS_POSIX)
morrita96693852014-09-24 20:11:4518#include "base/file_descriptor_posix.h"
morrita1aa788c2015-01-31 05:45:4219#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]7135bb042009-02-12 04:05:2820#endif
21
[email protected]2a2e3d62012-09-04 23:08:0922namespace {
23
tzikbc4270b2017-07-13 04:54:4924base::AtomicSequenceNumber g_ref_num;
[email protected]2a2e3d62012-09-04 23:08:0925
26// Create a reference number for identifying IPC messages in traces. The return
27// values has the reference number stored in the upper 24 bits, leaving the low
28// 8 bits set to 0 for use as flags.
tfarina10a5c062015-09-04 18:47:5729inline uint32_t GetRefNumUpper24() {
ssid759dd8c2015-02-09 21:25:3930 base::trace_event::TraceLog* trace_log =
31 base::trace_event::TraceLog::GetInstance();
tfarina10a5c062015-09-04 18:47:5732 uint32_t pid = trace_log ? trace_log->process_id() : 0;
33 uint32_t count = g_ref_num.GetNext();
[email protected]2a2e3d62012-09-04 23:08:0934 // The 24 bit hash is composed of 14 bits of the count and 10 bits of the
35 // Process ID. With the current trace event buffer cap, the 14-bit count did
36 // not appear to wrap during a trace. Note that it is not a big deal if
37 // collisions occur, as this is only used for debugging and trace analysis.
[email protected]40cb13052013-08-14 00:37:4738 return ((pid << 14) | (count & 0x3fff)) << 8;
[email protected]2a2e3d62012-09-04 23:08:0939}
40
41} // namespace
42
initial.commit09911bf2008-07-26 23:55:2943namespace IPC {
44
45//------------------------------------------------------------------------------
46
Chris Watkins2d879af2017-11-30 02:11:5947Message::~Message() = default;
initial.commit09911bf2008-07-26 23:55:2948
brettwbd4d7112015-06-03 04:29:2549Message::Message() : base::Pickle(sizeof(Header)) {
[email protected]2a2e3d62012-09-04 23:08:0950 header()->routing = header()->type = 0;
51 header()->flags = GetRefNumUpper24();
Fabrice de Gans-Riberi894661c2018-05-24 18:43:2252#if defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]526776c2009-02-07 00:39:2653 header()->num_fds = 0;
[email protected]15b97af032009-12-05 00:00:5854 header()->pad = 0;
[email protected]526776c2009-02-07 00:39:2655#endif
[email protected]ef2f6ba2014-05-15 23:06:0756 Init();
initial.commit09911bf2008-07-26 23:55:2957}
58
tfarina10a5c062015-09-04 18:47:5759Message::Message(int32_t routing_id, uint32_t type, PriorityValue priority)
brettwbd4d7112015-06-03 04:29:2560 : base::Pickle(sizeof(Header)) {
initial.commit09911bf2008-07-26 23:55:2961 header()->routing = routing_id;
62 header()->type = type;
[email protected]753bb252013-11-04 22:28:1263 DCHECK((priority & 0xffffff00) == 0);
64 header()->flags = priority | GetRefNumUpper24();
Fabrice de Gans-Riberi894661c2018-05-24 18:43:2265#if defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]526776c2009-02-07 00:39:2666 header()->num_fds = 0;
[email protected]15b97af032009-12-05 00:00:5867 header()->pad = 0;
[email protected]526776c2009-02-07 00:39:2668#endif
[email protected]ef2f6ba2014-05-15 23:06:0769 Init();
initial.commit09911bf2008-07-26 23:55:2970}
71
brettwbd4d7112015-06-03 04:29:2572Message::Message(const char* data, int data_len)
73 : base::Pickle(data, data_len) {
[email protected]ef2f6ba2014-05-15 23:06:0774 Init();
initial.commit09911bf2008-07-26 23:55:2975}
76
brettwbd4d7112015-06-03 04:29:2577Message::Message(const Message& other) : base::Pickle(other) {
[email protected]ef2f6ba2014-05-15 23:06:0778 Init();
morrita4b5c28e22015-01-14 21:17:0679 attachment_set_ = other.attachment_set_;
initial.commit09911bf2008-07-26 23:55:2980}
81
[email protected]ef2f6ba2014-05-15 23:06:0782void Message::Init() {
83 dispatch_error_ = false;
davidsz041528a2017-05-12 09:19:2384#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
initial.commit09911bf2008-07-26 23:55:2985 received_time_ = 0;
86 dont_log_ = false;
87 log_data_ = NULL;
88#endif
89}
90
91Message& Message::operator=(const Message& other) {
brettwbd4d7112015-06-03 04:29:2592 *static_cast<base::Pickle*>(this) = other;
morrita4b5c28e22015-01-14 21:17:0693 attachment_set_ = other.attachment_set_;
initial.commit09911bf2008-07-26 23:55:2994 return *this;
95}
96
tfarina10a5c062015-09-04 18:47:5797void Message::SetHeaderValues(int32_t routing, uint32_t type, uint32_t flags) {
[email protected]34d48612012-06-29 00:05:0498 // This should only be called when the message is already empty.
99 DCHECK(payload_size() == 0);
100
101 header()->routing = routing;
102 header()->type = type;
103 header()->flags = flags;
104}
105
morrita4b5c28e22015-01-14 21:17:06106void Message::EnsureMessageAttachmentSet() {
107 if (attachment_set_.get() == NULL)
108 attachment_set_ = new MessageAttachmentSet;
109}
110
davidsz041528a2017-05-12 09:19:23111#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
tfarina10a5c062015-09-04 18:47:57112void Message::set_sent_time(int64_t time) {
initial.commit09911bf2008-07-26 23:55:29113 DCHECK((header()->flags & HAS_SENT_TIME_BIT) == 0);
114 header()->flags |= HAS_SENT_TIME_BIT;
115 WriteInt64(time);
116}
117
tfarina10a5c062015-09-04 18:47:57118int64_t Message::sent_time() const {
initial.commit09911bf2008-07-26 23:55:29119 if ((header()->flags & HAS_SENT_TIME_BIT) == 0)
120 return 0;
121
122 const char* data = end_of_payload();
tfarina10a5c062015-09-04 18:47:57123 data -= sizeof(int64_t);
124 return *(reinterpret_cast<const int64_t*>(data));
initial.commit09911bf2008-07-26 23:55:29125}
126
tfarina10a5c062015-09-04 18:47:57127void Message::set_received_time(int64_t time) const {
initial.commit09911bf2008-07-26 23:55:29128 received_time_ = time;
129}
davidsz041528a2017-05-12 09:19:23130#endif // BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
initial.commit09911bf2008-07-26 23:55:29131
erikchen29e0f2f2015-09-11 19:08:53132Message::NextMessageInfo::NextMessageInfo()
dskiba6f3790a2015-09-30 17:24:30133 : message_size(0), message_found(false), pickle_end(nullptr),
134 message_end(nullptr) {}
Chris Watkins2d879af2017-11-30 02:11:59135Message::NextMessageInfo::~NextMessageInfo() = default;
erikchen29e0f2f2015-09-11 19:08:53136
137// static
138void Message::FindNext(const char* range_start,
139 const char* range_end,
140 NextMessageInfo* info) {
141 DCHECK(info);
dskiba6f3790a2015-09-30 17:24:30142 info->message_found = false;
143 info->message_size = 0;
144
145 size_t pickle_size = 0;
146 if (!base::Pickle::PeekNext(sizeof(Header),
147 range_start, range_end, &pickle_size))
erikchen29e0f2f2015-09-11 19:08:53148 return;
dskiba6f3790a2015-09-30 17:24:30149
150 bool have_entire_pickle =
151 static_cast<size_t>(range_end - range_start) >= pickle_size;
erikchen29e0f2f2015-09-11 19:08:53152
dskiba6f3790a2015-09-30 17:24:30153 info->message_size = pickle_size;
154
155 if (!have_entire_pickle)
156 return;
157
158 const char* pickle_end = range_start + pickle_size;
159
erikchen29e0f2f2015-09-11 19:08:53160 info->message_end = pickle_end;
erikchen29e0f2f2015-09-11 19:08:53161
dskiba6f3790a2015-09-30 17:24:30162 info->pickle_end = pickle_end;
erikchen29e0f2f2015-09-11 19:08:53163 info->message_found = true;
164}
165
rockot502c94f2016-02-03 20:20:16166bool Message::WriteAttachment(
167 scoped_refptr<base::Pickle::Attachment> attachment) {
erikchenae6d3212015-10-10 02:43:49168 size_t index;
rockot502c94f2016-02-03 20:20:16169 bool success = attachment_set()->AddAttachment(
kylecharda69d882017-10-04 05:49:52170 base::WrapRefCounted(static_cast<MessageAttachment*>(attachment.get())),
sammc6ed3efb2016-11-23 03:17:35171 &index);
erikchenae6d3212015-10-10 02:43:49172 DCHECK(success);
173
erikchenae6d3212015-10-10 02:43:49174 // Write the index of the descriptor so that we don't have to
[email protected]7135bb042009-02-12 04:05:28175 // keep the current descriptor as extra decoding state when deserialising.
erikchenae6d3212015-10-10 02:43:49176 WriteInt(static_cast<int>(index));
177
erikchenae6d3212015-10-10 02:43:49178 return success;
[email protected]7135bb042009-02-12 04:05:28179}
180
morrita1aa788c2015-01-31 05:45:42181bool Message::ReadAttachment(
brettwbd4d7112015-06-03 04:29:25182 base::PickleIterator* iter,
rockot502c94f2016-02-03 20:20:16183 scoped_refptr<base::Pickle::Attachment>* attachment) const {
erikchenae6d3212015-10-10 02:43:49184 int index;
185 if (!iter->ReadInt(&index))
[email protected]7135bb042009-02-12 04:05:28186 return false;
187
morrita4b5c28e22015-01-14 21:17:06188 MessageAttachmentSet* attachment_set = attachment_set_.get();
189 if (!attachment_set)
[email protected]7135bb042009-02-12 04:05:28190 return false;
191
sammc6ed3efb2016-11-23 03:17:35192 *attachment = attachment_set->GetAttachmentAt(index);
erikchenae6d3212015-10-10 02:43:49193
morrita1aa788c2015-01-31 05:45:42194 return nullptr != attachment->get();
[email protected]7135bb042009-02-12 04:05:28195}
196
morrita1aa788c2015-01-31 05:45:42197bool Message::HasAttachments() const {
morrita4b5c28e22015-01-14 21:17:06198 return attachment_set_.get() && !attachment_set_->empty();
[email protected]7135bb042009-02-12 04:05:28199}
200
[email protected]d284a5f2010-01-05 23:20:30201} // namespace IPC