Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(508)

Side by Side Diff: mojo/edk/system/channel.cc

Issue 2710193003: Adding a new message type to the Mojo channel. (Closed)
Patch Set: Addresed latest comments Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "mojo/edk/system/channel.h" 5 #include "mojo/edk/system/channel.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <limits> 10 #include <limits>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/memory/aligned_memory.h" 14 #include "base/memory/aligned_memory.h"
15 #include "base/process/process_handle.h" 15 #include "base/process/process_handle.h"
16 #include "mojo/edk/embedder/platform_handle.h" 16 #include "mojo/edk/embedder/platform_handle.h"
17 17
18 #if defined(OS_MACOSX) && !defined(OS_IOS) 18 #if defined(OS_MACOSX) && !defined(OS_IOS)
19 #include "base/mac/mach_logging.h" 19 #include "base/mac/mach_logging.h"
20 #elif defined(OS_WIN) 20 #elif defined(OS_WIN)
21 #include "base/win/win_util.h" 21 #include "base/win/win_util.h"
22 #endif 22 #endif
23 23
24 namespace mojo { 24 namespace mojo {
25 namespace edk { 25 namespace edk {
26 26
27 namespace { 27 namespace {
28 28
29 static_assert(sizeof(Channel::Message::Header) % kChannelMessageAlignment == 0, 29 static_assert(
30 "Invalid Header size."); 30 IsAlignedForChannelMessage(sizeof(Channel::Message::LegacyHeader)),
31 "Invalid LegacyHeader size.");
31 32
32 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 33 static_assert(IsAlignedForChannelMessage(sizeof(Channel::Message::Header)),
33 static_assert(sizeof(Channel::Message::Header) == 8, 34 "Invalid Header size.");
34 "Header must be 8 bytes on ChromeOS and Android"); 35
35 #endif 36 static_assert(sizeof(Channel::Message::LegacyHeader) == 8,
37 "LegacyHeader must be 8 bytes on ChromeOS and Android");
36 38
37 } // namespace 39 } // namespace
38 40
39 const size_t kReadBufferSize = 4096; 41 const size_t kReadBufferSize = 4096;
40 const size_t kMaxUnusedReadBufferCapacity = 4096; 42 const size_t kMaxUnusedReadBufferCapacity = 4096;
41 const size_t kMaxChannelMessageSize = 256 * 1024 * 1024; 43 const size_t kMaxChannelMessageSize = 256 * 1024 * 1024;
42 const size_t kMaxAttachedHandles = 128; 44 const size_t kMaxAttachedHandles = 128;
43 45
46 Channel::Message::Message(size_t payload_size, size_t max_handles)
47 #if defined(MOJO_EDK_LEGACY_PROTOCOL)
48 : Message(payload_size, max_handles, MessageType::NORMAL_LEGACY) {
49 }
50 #else
51 : Message(payload_size, max_handles, MessageType::NORMAL) {
52 }
53 #endif
54
44 Channel::Message::Message(size_t payload_size, 55 Channel::Message::Message(size_t payload_size,
45 size_t max_handles, 56 size_t max_handles,
46 Header::MessageType message_type) 57 MessageType message_type)
47 : max_handles_(max_handles) { 58 : max_handles_(max_handles) {
48 DCHECK_LE(max_handles_, kMaxAttachedHandles); 59 DCHECK_LE(max_handles_, kMaxAttachedHandles);
49 60
61 const bool is_legacy_message = (message_type == MessageType::NORMAL_LEGACY);
50 size_t extra_header_size = 0; 62 size_t extra_header_size = 0;
51 #if defined(OS_WIN) 63 #if defined(OS_WIN)
52 // On Windows we serialize HANDLEs into the extra header space. 64 // On Windows we serialize HANDLEs into the extra header space.
53 extra_header_size = max_handles_ * sizeof(HandleEntry); 65 extra_header_size = max_handles_ * sizeof(HandleEntry);
54 #elif defined(OS_MACOSX) && !defined(OS_IOS) 66 #elif defined(OS_MACOSX) && !defined(OS_IOS)
55 // On OSX, some of the platform handles may be mach ports, which are 67 // On OSX, some of the platform handles may be mach ports, which are
56 // serialised into the message buffer. Since there could be a mix of fds and 68 // serialised into the message buffer. Since there could be a mix of fds and
57 // mach ports, we store the mach ports as an <index, port> pair (of uint32_t), 69 // mach ports, we store the mach ports as an <index, port> pair (of uint32_t),
58 // so that the original ordering of handles can be re-created. 70 // so that the original ordering of handles can be re-created.
59 if (max_handles) { 71 if (max_handles) {
60 extra_header_size = 72 extra_header_size =
61 sizeof(MachPortsExtraHeader) + (max_handles * sizeof(MachPortsEntry)); 73 sizeof(MachPortsExtraHeader) + (max_handles * sizeof(MachPortsEntry));
62 } 74 }
63 #endif 75 #endif
64 // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes. 76 // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes.
65 if (extra_header_size % kChannelMessageAlignment) { 77 if (!IsAlignedForChannelMessage(extra_header_size)) {
66 extra_header_size += kChannelMessageAlignment - 78 extra_header_size += kChannelMessageAlignment -
67 (extra_header_size % kChannelMessageAlignment); 79 (extra_header_size % kChannelMessageAlignment);
68 } 80 }
69 DCHECK_EQ(0u, extra_header_size % kChannelMessageAlignment); 81 DCHECK(IsAlignedForChannelMessage(extra_header_size));
70 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 82 const size_t header_size =
71 DCHECK_EQ(0u, extra_header_size); 83 is_legacy_message ? sizeof(LegacyHeader) : sizeof(Header);
72 #endif 84 DCHECK(extra_header_size == 0 || !is_legacy_message);
73 85
74 size_ = sizeof(Header) + extra_header_size + payload_size; 86 size_ = header_size + extra_header_size + payload_size;
75 data_ = static_cast<char*>(base::AlignedAlloc(size_, 87 data_ = static_cast<char*>(base::AlignedAlloc(size_,
76 kChannelMessageAlignment)); 88 kChannelMessageAlignment));
77 // Only zero out the header and not the payload. Since the payload is going to 89 // Only zero out the header and not the payload. Since the payload is going to
78 // be memcpy'd, zeroing the payload is unnecessary work and a significant 90 // be memcpy'd, zeroing the payload is unnecessary work and a significant
79 // performance issue when dealing with large messages. Any sanitizer errors 91 // performance issue when dealing with large messages. Any sanitizer errors
80 // complaining about an uninitialized read in the payload area should be 92 // complaining about an uninitialized read in the payload area should be
81 // treated as an error and fixed. 93 // treated as an error and fixed.
82 memset(data_, 0, sizeof(Header) + extra_header_size); 94 memset(data_, 0, header_size + extra_header_size);
83 header_ = reinterpret_cast<Header*>(data_);
84 95
85 DCHECK_LE(size_, std::numeric_limits<uint32_t>::max()); 96 DCHECK_LE(size_, std::numeric_limits<uint32_t>::max());
86 header_->num_bytes = static_cast<uint32_t>(size_); 97 legacy_header()->num_bytes = static_cast<uint32_t>(size_);
87 98
88 DCHECK_LE(sizeof(Header) + extra_header_size, 99 DCHECK_LE(header_size + extra_header_size,
89 std::numeric_limits<uint16_t>::max()); 100 std::numeric_limits<uint16_t>::max());
90 header_->message_type = message_type; 101 legacy_header()->message_type = message_type;
91 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 102
92 header_->num_handles = static_cast<uint16_t>(max_handles); 103 if (is_legacy_message) {
93 #else 104 legacy_header()->num_handles = static_cast<uint16_t>(max_handles);
94 header_->num_header_bytes = 105 } else {
95 static_cast<uint16_t>(sizeof(Header) + extra_header_size); 106 header()->num_header_bytes =
96 #endif 107 static_cast<uint16_t>(header_size + extra_header_size);
108 }
97 109
98 if (max_handles_ > 0) { 110 if (max_handles_ > 0) {
99 #if defined(OS_WIN) 111 #if defined(OS_WIN)
100 handles_ = reinterpret_cast<HandleEntry*>(mutable_extra_header()); 112 handles_ = reinterpret_cast<HandleEntry*>(mutable_extra_header());
101 // Initialize all handles to invalid values. 113 // Initialize all handles to invalid values.
102 for (size_t i = 0; i < max_handles_; ++i) 114 for (size_t i = 0; i < max_handles_; ++i)
103 handles_[i].handle = base::win::HandleToUint32(INVALID_HANDLE_VALUE); 115 handles_[i].handle = base::win::HandleToUint32(INVALID_HANDLE_VALUE);
104 #elif defined(OS_MACOSX) && !defined(OS_IOS) 116 #elif defined(OS_MACOSX) && !defined(OS_IOS)
105 mach_ports_header_ = 117 mach_ports_header_ =
106 reinterpret_cast<MachPortsExtraHeader*>(mutable_extra_header()); 118 reinterpret_cast<MachPortsExtraHeader*>(mutable_extra_header());
107 mach_ports_header_->num_ports = 0; 119 mach_ports_header_->num_ports = 0;
108 // Initialize all handles to invalid values. 120 // Initialize all handles to invalid values.
109 for (size_t i = 0; i < max_handles_; ++i) { 121 for (size_t i = 0; i < max_handles_; ++i) {
110 mach_ports_header_->entries[i] = 122 mach_ports_header_->entries[i] =
111 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 123 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
112 } 124 }
113 #endif 125 #endif
114 } 126 }
115 } 127 }
116 128
117 Channel::Message::~Message() { 129 Channel::Message::~Message() {
118 base::AlignedFree(data_); 130 base::AlignedFree(data_);
119 } 131 }
120 132
121 // static 133 // static
122 Channel::MessagePtr Channel::Message::Deserialize(const void* data, 134 Channel::MessagePtr Channel::Message::Deserialize(const void* data,
123 size_t data_num_bytes) { 135 size_t data_num_bytes) {
124 if (data_num_bytes < sizeof(Header)) 136 if (data_num_bytes < sizeof(LegacyHeader))
125 return nullptr; 137 return nullptr;
126 138
127 const Header* header = reinterpret_cast<const Header*>(data); 139 const LegacyHeader* legacy_header =
128 if (header->num_bytes != data_num_bytes) { 140 reinterpret_cast<const LegacyHeader*>(data);
129 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes 141 if (legacy_header->num_bytes != data_num_bytes) {
142 DLOG(ERROR) << "Decoding invalid message: " << legacy_header->num_bytes
130 << " != " << data_num_bytes; 143 << " != " << data_num_bytes;
131 return nullptr; 144 return nullptr;
132 } 145 }
133 146
134 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 147 const Header* header = nullptr;
135 size_t payload_size = data_num_bytes - sizeof(Header); 148 if (legacy_header->message_type == MessageType::NORMAL)
136 const char* payload = static_cast<const char*>(data) + sizeof(Header); 149 header = reinterpret_cast<const Header*>(data);
137 #else 150
138 if (header->num_bytes < header->num_header_bytes || 151 uint32_t extra_header_size = 0;
139 header->num_header_bytes < sizeof(Header)) { 152 size_t payload_size = 0;
140 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < " 153 const char* payload = nullptr;
141 << header->num_header_bytes; 154 if (!header) {
142 return nullptr; 155 payload_size = data_num_bytes - sizeof(LegacyHeader);
156 payload = static_cast<const char*>(data) + sizeof(LegacyHeader);
157 } else {
158 if (header->num_bytes < header->num_header_bytes ||
159 header->num_header_bytes < sizeof(Header)) {
160 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < "
161 << header->num_header_bytes;
162 return nullptr;
163 }
164 extra_header_size = header->num_header_bytes - sizeof(Header);
165 payload_size = data_num_bytes - header->num_header_bytes;
166 payload = static_cast<const char*>(data) + header->num_header_bytes;
143 } 167 }
144 168
145 uint32_t extra_header_size = header->num_header_bytes - sizeof(Header);
146 size_t payload_size = data_num_bytes - header->num_header_bytes;
147 const char* payload =
148 static_cast<const char*>(data) + header->num_header_bytes;
149 #endif // defined(MOJO_EDK_LEGACY_PROTOCOL)
150
151 #if defined(OS_WIN) 169 #if defined(OS_WIN)
152 uint32_t max_handles = extra_header_size / sizeof(HandleEntry); 170 uint32_t max_handles = extra_header_size / sizeof(HandleEntry);
153 #elif defined(OS_MACOSX) && !defined(OS_IOS) 171 #elif defined(OS_MACOSX) && !defined(OS_IOS)
154 if (extra_header_size < sizeof(MachPortsExtraHeader)) { 172 if (extra_header_size < sizeof(MachPortsExtraHeader)) {
155 DLOG(ERROR) << "Decoding invalid message: " << extra_header_size << " < " 173 DLOG(ERROR) << "Decoding invalid message: " << extra_header_size << " < "
156 << sizeof(MachPortsExtraHeader); 174 << sizeof(MachPortsExtraHeader);
157 return nullptr; 175 return nullptr;
158 } 176 }
159 uint32_t max_handles = (extra_header_size - sizeof(MachPortsExtraHeader)) / 177 uint32_t max_handles = (extra_header_size - sizeof(MachPortsExtraHeader)) /
160 sizeof(MachPortsEntry); 178 sizeof(MachPortsEntry);
161 #else 179 #else
162 const uint32_t max_handles = 0; 180 const uint32_t max_handles = 0;
163 #endif // defined(OS_WIN) 181 #endif // defined(OS_WIN)
164 182
165 if (header->num_handles > max_handles || max_handles > kMaxAttachedHandles) { 183 const uint16_t num_handles =
166 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles 184 header ? header->num_handles : legacy_header->num_handles;
167 << " > " << max_handles; 185 if (num_handles > max_handles || max_handles > kMaxAttachedHandles) {
186 DLOG(ERROR) << "Decoding invalid message: " << num_handles << " > "
187 << max_handles;
168 return nullptr; 188 return nullptr;
169 } 189 }
170 190
171 MessagePtr message(new Message(payload_size, max_handles)); 191 MessagePtr message(
192 new Message(payload_size, max_handles, legacy_header->message_type));
172 DCHECK_EQ(message->data_num_bytes(), data_num_bytes); 193 DCHECK_EQ(message->data_num_bytes(), data_num_bytes);
173 194
174 // Copy all payload bytes. 195 // Copy all payload bytes.
175 if (payload_size) 196 if (payload_size)
176 memcpy(message->mutable_payload(), payload, payload_size); 197 memcpy(message->mutable_payload(), payload, payload_size);
177 198
178 #if !defined(MOJO_EDK_LEGACY_PROTOCOL) 199 if (header) {
179 DCHECK_EQ(message->extra_header_size(), extra_header_size); 200 DCHECK_EQ(message->extra_header_size(), extra_header_size);
180 DCHECK_EQ(message->header_->num_header_bytes, header->num_header_bytes); 201 DCHECK_EQ(message->header()->num_header_bytes, header->num_header_bytes);
181 202
182 if (message->extra_header_size()) { 203 if (message->extra_header_size()) {
183 // Copy extra header bytes. 204 // Copy extra header bytes.
184 memcpy(message->mutable_extra_header(), 205 memcpy(message->mutable_extra_header(),
185 static_cast<const char*>(data) + sizeof(Header), 206 static_cast<const char*>(data) + sizeof(Header),
186 message->extra_header_size()); 207 message->extra_header_size());
208 }
209 message->header()->num_handles = header->num_handles;
210 } else {
211 message->legacy_header()->num_handles = legacy_header->num_handles;
187 } 212 }
188 #endif
189 213
190 message->header_->num_handles = header->num_handles;
191 #if defined(OS_WIN) 214 #if defined(OS_WIN)
192 ScopedPlatformHandleVectorPtr handles( 215 ScopedPlatformHandleVectorPtr handles(new PlatformHandleVector(num_handles));
193 new PlatformHandleVector(header->num_handles)); 216 for (size_t i = 0; i < num_handles; i++) {
194 for (size_t i = 0; i < header->num_handles; i++) {
195 (*handles)[i].handle = 217 (*handles)[i].handle =
196 base::win::Uint32ToHandle(message->handles_[i].handle); 218 base::win::Uint32ToHandle(message->handles_[i].handle);
197 } 219 }
198 message->SetHandles(std::move(handles)); 220 message->SetHandles(std::move(handles));
199 #endif 221 #endif
200 222
201 return message; 223 return message;
202 } 224 }
203 225
226 const void* Channel::Message::extra_header() const {
227 DCHECK(!is_legacy_message());
228 return data_ + sizeof(Header);
229 }
230
231 void* Channel::Message::mutable_extra_header() {
232 DCHECK(!is_legacy_message());
233 return data_ + sizeof(Header);
234 }
235
236 size_t Channel::Message::extra_header_size() const {
237 return header()->num_header_bytes - sizeof(Header);
238 }
239
240 void* Channel::Message::mutable_payload() {
241 if (is_legacy_message())
242 return static_cast<void*>(legacy_header() + 1);
243 return data_ + header()->num_header_bytes;
244 }
245
246 const void* Channel::Message::payload() const {
247 if (is_legacy_message())
248 return static_cast<const void*>(legacy_header() + 1);
249 return data_ + header()->num_header_bytes;
250 }
251
204 size_t Channel::Message::payload_size() const { 252 size_t Channel::Message::payload_size() const {
205 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 253 if (is_legacy_message())
206 return header_->num_bytes - sizeof(Header); 254 return legacy_header()->num_bytes - sizeof(LegacyHeader);
207 #else 255 return size_ - header()->num_header_bytes;
208 return size_ - header_->num_header_bytes; 256 }
209 #endif 257
258 size_t Channel::Message::num_handles() const {
259 return is_legacy_message() ? legacy_header()->num_handles
260 : header()->num_handles;
261 }
262
263 bool Channel::Message::has_handles() const {
264 return (is_legacy_message() ? legacy_header()->num_handles
265 : header()->num_handles) > 0;
210 } 266 }
211 267
212 #if defined(OS_MACOSX) && !defined(OS_IOS) 268 #if defined(OS_MACOSX) && !defined(OS_IOS)
213 bool Channel::Message::has_mach_ports() const { 269 bool Channel::Message::has_mach_ports() const {
214 if (!has_handles()) 270 if (!has_handles())
215 return false; 271 return false;
216 272
217 for (const auto& handle : (*handle_vector_)) { 273 for (const auto& handle : (*handle_vector_)) {
218 if (handle.type == PlatformHandle::Type::MACH || 274 if (handle.type == PlatformHandle::Type::MACH ||
219 handle.type == PlatformHandle::Type::MACH_NAME) { 275 handle.type == PlatformHandle::Type::MACH_NAME) {
220 return true; 276 return true;
221 } 277 }
222 } 278 }
223 return false; 279 return false;
224 } 280 }
225 #endif 281 #endif
226 282
283 bool Channel::Message::is_legacy_message() const {
284 return legacy_header()->message_type == MessageType::NORMAL_LEGACY;
285 }
286
287 Channel::Message::LegacyHeader* Channel::Message::legacy_header() const {
288 return reinterpret_cast<LegacyHeader*>(data_);
289 }
290
291 Channel::Message::Header* Channel::Message::header() const {
292 DCHECK(!is_legacy_message());
293 return reinterpret_cast<Header*>(data_);
294 }
295
227 void Channel::Message::SetHandles(ScopedPlatformHandleVectorPtr new_handles) { 296 void Channel::Message::SetHandles(ScopedPlatformHandleVectorPtr new_handles) {
228 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 297 if (is_legacy_message()) {
229 // Old semantics for ChromeOS and Android 298 // Old semantics for ChromeOS and Android
230 if (header_->num_handles == 0) { 299 if (legacy_header()->num_handles == 0) {
231 CHECK(!new_handles || new_handles->size() == 0); 300 CHECK(!new_handles || new_handles->size() == 0);
301 return;
302 }
303 CHECK(new_handles && new_handles->size() == legacy_header()->num_handles);
304 std::swap(handle_vector_, new_handles);
232 return; 305 return;
233 } 306 }
234 CHECK(new_handles && new_handles->size() == header_->num_handles);
235 std::swap(handle_vector_, new_handles);
236 307
237 #else
238 if (max_handles_ == 0) { 308 if (max_handles_ == 0) {
239 CHECK(!new_handles || new_handles->size() == 0); 309 CHECK(!new_handles || new_handles->size() == 0);
240 return; 310 return;
241 } 311 }
242 312
243 CHECK(new_handles && new_handles->size() <= max_handles_); 313 CHECK(new_handles && new_handles->size() <= max_handles_);
244 header_->num_handles = static_cast<uint16_t>(new_handles->size()); 314 header()->num_handles = static_cast<uint16_t>(new_handles->size());
245 std::swap(handle_vector_, new_handles); 315 std::swap(handle_vector_, new_handles);
246 #if defined(OS_WIN) 316 #if defined(OS_WIN)
247 memset(handles_, 0, extra_header_size()); 317 memset(handles_, 0, extra_header_size());
248 for (size_t i = 0; i < handle_vector_->size(); i++) 318 for (size_t i = 0; i < handle_vector_->size(); i++)
249 handles_[i].handle = base::win::HandleToUint32((*handle_vector_)[i].handle); 319 handles_[i].handle = base::win::HandleToUint32((*handle_vector_)[i].handle);
250 #endif // defined(OS_WIN) 320 #endif // defined(OS_WIN)
251 #endif // defined(MOJO_EDK_LEGACY_PROTOCOL)
252 321
253 #if defined(OS_MACOSX) && !defined(OS_IOS) 322 #if defined(OS_MACOSX) && !defined(OS_IOS)
254 size_t mach_port_index = 0; 323 size_t mach_port_index = 0;
255 if (mach_ports_header_) { 324 if (mach_ports_header_) {
256 for (size_t i = 0; i < max_handles_; ++i) { 325 for (size_t i = 0; i < max_handles_; ++i) {
257 mach_ports_header_->entries[i] = 326 mach_ports_header_->entries[i] =
258 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 327 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
259 } 328 }
260 for (size_t i = 0; i < handle_vector_->size(); i++) { 329 for (size_t i = 0; i < handle_vector_->size(); i++) {
261 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH || 330 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH ||
(...skipping 11 matching lines...) Expand all
273 342
274 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() { 343 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() {
275 #if defined(OS_MACOSX) && !defined(OS_IOS) 344 #if defined(OS_MACOSX) && !defined(OS_IOS)
276 if (mach_ports_header_) { 345 if (mach_ports_header_) {
277 for (size_t i = 0; i < max_handles_; ++i) { 346 for (size_t i = 0; i < max_handles_; ++i) {
278 mach_ports_header_->entries[i] = 347 mach_ports_header_->entries[i] =
279 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 348 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
280 } 349 }
281 mach_ports_header_->num_ports = 0; 350 mach_ports_header_->num_ports = 0;
282 } 351 }
283 header_->num_handles = 0; 352 #endif
353 if (is_legacy_message())
354 legacy_header()->num_handles = 0;
355 else
356 header()->num_handles = 0;
284 return std::move(handle_vector_); 357 return std::move(handle_vector_);
285 #else
286 header_->num_handles = 0;
287 return std::move(handle_vector_);
288 #endif
289 } 358 }
290 359
291 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandlesForTransport() { 360 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandlesForTransport() {
292 #if defined(OS_WIN) 361 #if defined(OS_WIN)
293 // Not necessary on Windows. 362 // Not necessary on Windows.
294 NOTREACHED(); 363 NOTREACHED();
295 return nullptr; 364 return nullptr;
296 #elif defined(OS_MACOSX) && !defined(OS_IOS) 365 #elif defined(OS_MACOSX) && !defined(OS_IOS)
297 if (handle_vector_) { 366 if (handle_vector_) {
298 for (auto it = handle_vector_->begin(); it != handle_vector_->end(); ) { 367 for (auto it = handle_vector_->begin(); it != handle_vector_->end(); ) {
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 if (!required_capacity) 553 if (!required_capacity)
485 required_capacity = kReadBufferSize; 554 required_capacity = kReadBufferSize;
486 555
487 *buffer_capacity = required_capacity; 556 *buffer_capacity = required_capacity;
488 return read_buffer_->Reserve(required_capacity); 557 return read_buffer_->Reserve(required_capacity);
489 } 558 }
490 559
491 bool Channel::OnReadComplete(size_t bytes_read, size_t *next_read_size_hint) { 560 bool Channel::OnReadComplete(size_t bytes_read, size_t *next_read_size_hint) {
492 bool did_dispatch_message = false; 561 bool did_dispatch_message = false;
493 read_buffer_->Claim(bytes_read); 562 read_buffer_->Claim(bytes_read);
494 while (read_buffer_->num_occupied_bytes() >= sizeof(Message::Header)) { 563 while (read_buffer_->num_occupied_bytes() >= sizeof(Message::LegacyHeader)) {
495 // Ensure the occupied data is properly aligned. If it isn't, a SIGBUS could 564 // Ensure the occupied data is properly aligned. If it isn't, a SIGBUS could
496 // happen on architectures that don't allow misaligned words access (i.e. 565 // happen on architectures that don't allow misaligned words access (i.e.
497 // anything other than x86). Only re-align when necessary to avoid copies. 566 // anything other than x86). Only re-align when necessary to avoid copies.
498 if (reinterpret_cast<uintptr_t>(read_buffer_->occupied_bytes()) % 567 if (!IsAlignedForChannelMessage(
499 kChannelMessageAlignment != 0) 568 reinterpret_cast<uintptr_t>(read_buffer_->occupied_bytes()))) {
500 read_buffer_->Realign(); 569 read_buffer_->Realign();
570 }
501 571
502 // We have at least enough data available for a MessageHeader. 572 // We have at least enough data available for a LegacyHeader.
503 const Message::Header* header = reinterpret_cast<const Message::Header*>( 573 const Message::LegacyHeader* legacy_header =
504 read_buffer_->occupied_bytes()); 574 reinterpret_cast<const Message::LegacyHeader*>(
505 if (header->num_bytes < sizeof(Message::Header) || 575 read_buffer_->occupied_bytes());
506 header->num_bytes > kMaxChannelMessageSize) { 576
507 LOG(ERROR) << "Invalid message size: " << header->num_bytes; 577 if (legacy_header->num_bytes < sizeof(Message::LegacyHeader) ||
578 legacy_header->num_bytes > kMaxChannelMessageSize) {
579 LOG(ERROR) << "Invalid message size: " << legacy_header->num_bytes;
508 return false; 580 return false;
509 } 581 }
510 582
511 if (read_buffer_->num_occupied_bytes() < header->num_bytes) { 583 if (read_buffer_->num_occupied_bytes() < legacy_header->num_bytes) {
512 // Not enough data available to read the full message. Hint to the 584 // Not enough data available to read the full message. Hint to the
513 // implementation that it should try reading the full size of the message. 585 // implementation that it should try reading the full size of the message.
514 *next_read_size_hint = 586 *next_read_size_hint =
515 header->num_bytes - read_buffer_->num_occupied_bytes(); 587 legacy_header->num_bytes - read_buffer_->num_occupied_bytes();
516 return true; 588 return true;
517 } 589 }
518 590
519 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 591 const Message::Header* header = nullptr;
592 if (legacy_header->message_type != Message::MessageType::NORMAL_LEGACY) {
593 header = reinterpret_cast<const Message::Header*>(legacy_header);
594 }
595
520 size_t extra_header_size = 0; 596 size_t extra_header_size = 0;
521 const void* extra_header = nullptr; 597 const void* extra_header = nullptr;
522 size_t payload_size = header->num_bytes - sizeof(Message::Header); 598 size_t payload_size = 0;
523 void* payload = payload_size ? const_cast<Message::Header*>(&header[1]) 599 void* payload = nullptr;
524 : nullptr; 600 if (header) {
525 #else 601 if (header->num_header_bytes < sizeof(Message::Header) ||
526 if (header->num_header_bytes < sizeof(Message::Header) || 602 header->num_header_bytes > header->num_bytes) {
527 header->num_header_bytes > header->num_bytes) { 603 LOG(ERROR) << "Invalid message header size: "
528 LOG(ERROR) << "Invalid message header size: " << header->num_header_bytes; 604 << header->num_header_bytes;
529 return false; 605 return false;
606 }
607 extra_header_size = header->num_header_bytes - sizeof(Message::Header);
608 extra_header = extra_header_size ? header + 1 : nullptr;
609 payload_size = header->num_bytes - header->num_header_bytes;
610 payload = payload_size
611 ? reinterpret_cast<Message::Header*>(
612 const_cast<char*>(read_buffer_->occupied_bytes()) +
613 header->num_header_bytes)
614 : nullptr;
615 } else {
616 payload_size = legacy_header->num_bytes - sizeof(Message::LegacyHeader);
617 payload = payload_size
618 ? const_cast<Message::LegacyHeader*>(&legacy_header[1])
619 : nullptr;
530 } 620 }
531 size_t extra_header_size =
532 header->num_header_bytes - sizeof(Message::Header);
533 const void* extra_header = extra_header_size ? header + 1 : nullptr;
534 size_t payload_size = header->num_bytes - header->num_header_bytes;
535 void* payload =
536 payload_size ? reinterpret_cast<Message::Header*>(
537 const_cast<char*>(read_buffer_->occupied_bytes()) +
538 header->num_header_bytes)
539 : nullptr;
540 #endif // defined(MOJO_EDK_LEGACY_PROTOCOL)
541 621
622 const uint16_t num_handles =
623 header ? header->num_handles : legacy_header->num_handles;
542 ScopedPlatformHandleVectorPtr handles; 624 ScopedPlatformHandleVectorPtr handles;
543 if (header->num_handles > 0) { 625 if (num_handles > 0) {
544 if (!GetReadPlatformHandles(header->num_handles, extra_header, 626 if (!GetReadPlatformHandles(num_handles, extra_header, extra_header_size,
545 extra_header_size, &handles)) { 627 &handles)) {
546 return false; 628 return false;
547 } 629 }
548 630
549 if (!handles) { 631 if (!handles) {
550 // Not enough handles available for this message. 632 // Not enough handles available for this message.
551 break; 633 break;
552 } 634 }
553 } 635 }
554 636
555 // We've got a complete message! Dispatch it and try another. 637 // We've got a complete message! Dispatch it and try another.
556 if (header->message_type != Message::Header::MessageType::NORMAL) { 638 if (legacy_header->message_type != Message::MessageType::NORMAL_LEGACY &&
557 if (!OnControlMessage(header->message_type, payload, payload_size, 639 legacy_header->message_type != Message::MessageType::NORMAL) {
640 if (!OnControlMessage(legacy_header->message_type, payload, payload_size,
558 std::move(handles))) { 641 std::move(handles))) {
559 return false; 642 return false;
560 } 643 }
561 did_dispatch_message = true; 644 did_dispatch_message = true;
562 } else if (delegate_) { 645 } else if (delegate_) {
563 delegate_->OnChannelMessage(payload, payload_size, std::move(handles)); 646 delegate_->OnChannelMessage(payload, payload_size, std::move(handles));
564 did_dispatch_message = true; 647 did_dispatch_message = true;
565 } 648 }
566 649
567 read_buffer_->Discard(header->num_bytes); 650 read_buffer_->Discard(legacy_header->num_bytes);
568 } 651 }
569 652
570 *next_read_size_hint = did_dispatch_message ? 0 : kReadBufferSize; 653 *next_read_size_hint = did_dispatch_message ? 0 : kReadBufferSize;
571 return true; 654 return true;
572 } 655 }
573 656
574 void Channel::OnError() { 657 void Channel::OnError() {
575 if (delegate_) 658 if (delegate_)
576 delegate_->OnChannelError(); 659 delegate_->OnChannelError();
577 } 660 }
578 661
579 bool Channel::OnControlMessage(Message::Header::MessageType message_type, 662 bool Channel::OnControlMessage(Message::MessageType message_type,
580 const void* payload, 663 const void* payload,
581 size_t payload_size, 664 size_t payload_size,
582 ScopedPlatformHandleVectorPtr handles) { 665 ScopedPlatformHandleVectorPtr handles) {
583 return false; 666 return false;
584 } 667 }
585 668
586 } // namespace edk 669 } // namespace edk
587 } // namespace mojo 670 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698