OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ipc/ipc_message.h" | 5 #include "ipc/ipc_message.h" |
6 | 6 |
7 #include <limits.h> | 7 #include <limits.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
11 #include "base/atomic_sequence_num.h" | 11 #include "base/atomic_sequence_num.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "build/build_config.h" | 13 #include "build/build_config.h" |
14 #include "ipc/attachment_broker.h" | |
15 #include "ipc/ipc_message_attachment.h" | 14 #include "ipc/ipc_message_attachment.h" |
16 #include "ipc/ipc_message_attachment_set.h" | 15 #include "ipc/ipc_message_attachment_set.h" |
17 #include "ipc/placeholder_brokerable_attachment.h" | |
18 | 16 |
19 #if defined(OS_POSIX) | 17 #if defined(OS_POSIX) |
20 #include "base/file_descriptor_posix.h" | 18 #include "base/file_descriptor_posix.h" |
21 #include "ipc/ipc_platform_file_attachment_posix.h" | 19 #include "ipc/ipc_platform_file_attachment_posix.h" |
22 #endif | 20 #endif |
23 | 21 |
24 namespace { | 22 namespace { |
25 | 23 |
26 base::StaticAtomicSequenceNumber g_ref_num; | 24 base::StaticAtomicSequenceNumber g_ref_num; |
27 | 25 |
(...skipping 17 matching lines...) Expand all Loading... |
45 namespace IPC { | 43 namespace IPC { |
46 | 44 |
47 //------------------------------------------------------------------------------ | 45 //------------------------------------------------------------------------------ |
48 | 46 |
49 Message::~Message() { | 47 Message::~Message() { |
50 } | 48 } |
51 | 49 |
52 Message::Message() : base::Pickle(sizeof(Header)) { | 50 Message::Message() : base::Pickle(sizeof(Header)) { |
53 header()->routing = header()->type = 0; | 51 header()->routing = header()->type = 0; |
54 header()->flags = GetRefNumUpper24(); | 52 header()->flags = GetRefNumUpper24(); |
55 #if USE_ATTACHMENT_BROKER | |
56 header()->num_brokered_attachments = 0; | |
57 #endif | |
58 #if defined(OS_POSIX) | 53 #if defined(OS_POSIX) |
59 header()->num_fds = 0; | 54 header()->num_fds = 0; |
60 header()->pad = 0; | 55 header()->pad = 0; |
61 #endif | 56 #endif |
62 Init(); | 57 Init(); |
63 } | 58 } |
64 | 59 |
65 Message::Message(int32_t routing_id, uint32_t type, PriorityValue priority) | 60 Message::Message(int32_t routing_id, uint32_t type, PriorityValue priority) |
66 : base::Pickle(sizeof(Header)) { | 61 : base::Pickle(sizeof(Header)) { |
67 header()->routing = routing_id; | 62 header()->routing = routing_id; |
68 header()->type = type; | 63 header()->type = type; |
69 DCHECK((priority & 0xffffff00) == 0); | 64 DCHECK((priority & 0xffffff00) == 0); |
70 header()->flags = priority | GetRefNumUpper24(); | 65 header()->flags = priority | GetRefNumUpper24(); |
71 #if USE_ATTACHMENT_BROKER | |
72 header()->num_brokered_attachments = 0; | |
73 #endif | |
74 #if defined(OS_POSIX) | 66 #if defined(OS_POSIX) |
75 header()->num_fds = 0; | 67 header()->num_fds = 0; |
76 header()->pad = 0; | 68 header()->pad = 0; |
77 #endif | 69 #endif |
78 Init(); | 70 Init(); |
79 } | 71 } |
80 | 72 |
81 Message::Message(const char* data, int data_len) | 73 Message::Message(const char* data, int data_len) |
82 : base::Pickle(data, data_len) { | 74 : base::Pickle(data, data_len) { |
83 Init(); | 75 Init(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 void Message::set_received_time(int64_t time) const { | 131 void Message::set_received_time(int64_t time) const { |
140 received_time_ = time; | 132 received_time_ = time; |
141 } | 133 } |
142 #endif | 134 #endif |
143 | 135 |
144 Message::NextMessageInfo::NextMessageInfo() | 136 Message::NextMessageInfo::NextMessageInfo() |
145 : message_size(0), message_found(false), pickle_end(nullptr), | 137 : message_size(0), message_found(false), pickle_end(nullptr), |
146 message_end(nullptr) {} | 138 message_end(nullptr) {} |
147 Message::NextMessageInfo::~NextMessageInfo() {} | 139 Message::NextMessageInfo::~NextMessageInfo() {} |
148 | 140 |
149 Message::SerializedAttachmentIds | |
150 Message::SerializedIdsOfBrokerableAttachments() { | |
151 DCHECK(HasBrokerableAttachments()); | |
152 std::vector<scoped_refptr<IPC::BrokerableAttachment>> attachments( | |
153 attachment_set_->GetBrokerableAttachments()); | |
154 CHECK_LE(attachments.size(), std::numeric_limits<size_t>::max() / | |
155 BrokerableAttachment::kNonceSize); | |
156 size_t size = attachments.size() * BrokerableAttachment::kNonceSize; | |
157 char* buffer = static_cast<char*>(malloc(size)); | |
158 for (size_t i = 0; i < attachments.size(); ++i) { | |
159 char* start_range = buffer + i * BrokerableAttachment::kNonceSize; | |
160 BrokerableAttachment::AttachmentId id = attachments[i]->GetIdentifier(); | |
161 id.SerializeToBuffer(start_range, BrokerableAttachment::kNonceSize); | |
162 } | |
163 SerializedAttachmentIds ids; | |
164 ids.buffer = buffer; | |
165 ids.size = size; | |
166 return ids; | |
167 } | |
168 | |
169 // static | 141 // static |
170 void Message::FindNext(const char* range_start, | 142 void Message::FindNext(const char* range_start, |
171 const char* range_end, | 143 const char* range_end, |
172 NextMessageInfo* info) { | 144 NextMessageInfo* info) { |
173 DCHECK(info); | 145 DCHECK(info); |
174 info->message_found = false; | 146 info->message_found = false; |
175 info->message_size = 0; | 147 info->message_size = 0; |
176 | 148 |
177 size_t pickle_size = 0; | 149 size_t pickle_size = 0; |
178 if (!base::Pickle::PeekNext(sizeof(Header), | 150 if (!base::Pickle::PeekNext(sizeof(Header), |
179 range_start, range_end, &pickle_size)) | 151 range_start, range_end, &pickle_size)) |
180 return; | 152 return; |
181 | 153 |
182 bool have_entire_pickle = | 154 bool have_entire_pickle = |
183 static_cast<size_t>(range_end - range_start) >= pickle_size; | 155 static_cast<size_t>(range_end - range_start) >= pickle_size; |
184 | 156 |
185 #if USE_ATTACHMENT_BROKER | |
186 // TODO(dskiba): determine message_size when entire pickle is not available | |
187 | |
188 if (!have_entire_pickle) | |
189 return; | |
190 | |
191 const char* pickle_end = range_start + pickle_size; | |
192 | |
193 // The data is not copied. | |
194 Message message(range_start, static_cast<int>(pickle_size)); | |
195 size_t num_attachments = message.header()->num_brokered_attachments; | |
196 | |
197 // Check for possible overflows. | |
198 size_t max_size_t = std::numeric_limits<size_t>::max(); | |
199 if (num_attachments >= max_size_t / BrokerableAttachment::kNonceSize) | |
200 return; | |
201 | |
202 size_t attachment_length = num_attachments * BrokerableAttachment::kNonceSize; | |
203 if (pickle_size > max_size_t - attachment_length) | |
204 return; | |
205 | |
206 // Check whether the range includes the attachments. | |
207 size_t buffer_length = static_cast<size_t>(range_end - range_start); | |
208 if (buffer_length < attachment_length + pickle_size) | |
209 return; | |
210 | |
211 for (size_t i = 0; i < num_attachments; ++i) { | |
212 const char* attachment_start = | |
213 pickle_end + i * BrokerableAttachment::kNonceSize; | |
214 BrokerableAttachment::AttachmentId id(attachment_start, | |
215 BrokerableAttachment::kNonceSize); | |
216 info->attachment_ids.push_back(id); | |
217 } | |
218 info->message_end = | |
219 pickle_end + num_attachments * BrokerableAttachment::kNonceSize; | |
220 info->message_size = info->message_end - range_start; | |
221 #else | |
222 info->message_size = pickle_size; | 157 info->message_size = pickle_size; |
223 | 158 |
224 if (!have_entire_pickle) | 159 if (!have_entire_pickle) |
225 return; | 160 return; |
226 | 161 |
227 const char* pickle_end = range_start + pickle_size; | 162 const char* pickle_end = range_start + pickle_size; |
228 | 163 |
229 info->message_end = pickle_end; | 164 info->message_end = pickle_end; |
230 #endif // USE_ATTACHMENT_BROKER | |
231 | 165 |
232 info->pickle_end = pickle_end; | 166 info->pickle_end = pickle_end; |
233 info->message_found = true; | 167 info->message_found = true; |
234 } | 168 } |
235 | 169 |
236 bool Message::AddPlaceholderBrokerableAttachmentWithId( | |
237 BrokerableAttachment::AttachmentId id) { | |
238 scoped_refptr<PlaceholderBrokerableAttachment> attachment( | |
239 new PlaceholderBrokerableAttachment(id)); | |
240 return attachment_set()->AddAttachment(attachment); | |
241 } | |
242 | |
243 bool Message::WriteAttachment( | 170 bool Message::WriteAttachment( |
244 scoped_refptr<base::Pickle::Attachment> attachment) { | 171 scoped_refptr<base::Pickle::Attachment> attachment) { |
245 bool brokerable; | 172 bool brokerable; |
246 size_t index; | 173 size_t index; |
247 bool success = attachment_set()->AddAttachment( | 174 bool success = attachment_set()->AddAttachment( |
248 make_scoped_refptr(static_cast<MessageAttachment*>(attachment.get())), | 175 make_scoped_refptr(static_cast<MessageAttachment*>(attachment.get())), |
249 &index, &brokerable); | 176 &index, &brokerable); |
250 DCHECK(success); | 177 DCHECK(success); |
251 | 178 |
252 // NOTE: If you add more data to the pickle, make sure to update | 179 // NOTE: If you add more data to the pickle, make sure to update |
253 // PickleSizer::AddAttachment. | 180 // PickleSizer::AddAttachment. |
254 | 181 |
255 // Write the type of descriptor. | 182 // Write the type of descriptor. |
256 WriteBool(brokerable); | 183 WriteBool(brokerable); |
257 | 184 |
258 // Write the index of the descriptor so that we don't have to | 185 // Write the index of the descriptor so that we don't have to |
259 // keep the current descriptor as extra decoding state when deserialising. | 186 // keep the current descriptor as extra decoding state when deserialising. |
260 WriteInt(static_cast<int>(index)); | 187 WriteInt(static_cast<int>(index)); |
261 | 188 |
262 #if USE_ATTACHMENT_BROKER | |
263 if (brokerable) | |
264 header()->num_brokered_attachments++; | |
265 #endif | |
266 | |
267 return success; | 189 return success; |
268 } | 190 } |
269 | 191 |
270 bool Message::ReadAttachment( | 192 bool Message::ReadAttachment( |
271 base::PickleIterator* iter, | 193 base::PickleIterator* iter, |
272 scoped_refptr<base::Pickle::Attachment>* attachment) const { | 194 scoped_refptr<base::Pickle::Attachment>* attachment) const { |
273 bool brokerable; | 195 bool brokerable; |
274 if (!iter->ReadBool(&brokerable)) | 196 if (!iter->ReadBool(&brokerable)) |
275 return false; | 197 return false; |
276 | 198 |
(...skipping 19 matching lines...) Expand all Loading... |
296 bool Message::HasMojoHandles() const { | 218 bool Message::HasMojoHandles() const { |
297 return attachment_set_.get() && attachment_set_->num_mojo_handles() > 0; | 219 return attachment_set_.get() && attachment_set_->num_mojo_handles() > 0; |
298 } | 220 } |
299 | 221 |
300 bool Message::HasBrokerableAttachments() const { | 222 bool Message::HasBrokerableAttachments() const { |
301 return attachment_set_.get() && | 223 return attachment_set_.get() && |
302 attachment_set_->num_brokerable_attachments() > 0; | 224 attachment_set_->num_brokerable_attachments() > 0; |
303 } | 225 } |
304 | 226 |
305 } // namespace IPC | 227 } // namespace IPC |
OLD | NEW |