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

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

Issue 2710193003: Adding a new message type to the Mojo channel. (Closed)
Patch Set: Removed versioning from Header. 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 size_t header_size;
Ken Rockot(use gerrit already) 2017/02/28 16:58:32 Let's maybe make header_size a constexpr and use a
Jay Civelli 2017/02/28 17:13:05 It can be const but not constexpr since it depends
71 DCHECK_EQ(0u, extra_header_size); 83 if (is_legacy_message) {
72 #endif 84 header_size = sizeof(LegacyHeader);
85 DCHECK_EQ(0u, extra_header_size);
86 } else {
87 header_size = sizeof(Header);
88 }
73 89
74 size_ = sizeof(Header) + extra_header_size + payload_size; 90 size_ = header_size + extra_header_size + payload_size;
75 data_ = static_cast<char*>(base::AlignedAlloc(size_, 91 data_ = static_cast<char*>(base::AlignedAlloc(size_,
76 kChannelMessageAlignment)); 92 kChannelMessageAlignment));
77 // Only zero out the header and not the payload. Since the payload is going to 93 // 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 94 // be memcpy'd, zeroing the payload is unnecessary work and a significant
79 // performance issue when dealing with large messages. Any sanitizer errors 95 // performance issue when dealing with large messages. Any sanitizer errors
80 // complaining about an uninitialized read in the payload area should be 96 // complaining about an uninitialized read in the payload area should be
81 // treated as an error and fixed. 97 // treated as an error and fixed.
82 memset(data_, 0, sizeof(Header) + extra_header_size); 98 memset(data_, 0, header_size + extra_header_size);
83 header_ = reinterpret_cast<Header*>(data_);
84 99
85 DCHECK_LE(size_, std::numeric_limits<uint32_t>::max()); 100 DCHECK_LE(size_, std::numeric_limits<uint32_t>::max());
86 header_->num_bytes = static_cast<uint32_t>(size_); 101 legacy_header()->num_bytes = static_cast<uint32_t>(size_);
87 102
88 DCHECK_LE(sizeof(Header) + extra_header_size, 103 DCHECK_LE(header_size + extra_header_size,
89 std::numeric_limits<uint16_t>::max()); 104 std::numeric_limits<uint16_t>::max());
90 header_->message_type = message_type; 105 legacy_header()->message_type = message_type;
91 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 106
92 header_->num_handles = static_cast<uint16_t>(max_handles); 107 if (is_legacy_message) {
93 #else 108 legacy_header()->num_handles = static_cast<uint16_t>(max_handles);
94 header_->num_header_bytes = 109 } else {
95 static_cast<uint16_t>(sizeof(Header) + extra_header_size); 110 header()->num_header_bytes =
96 #endif 111 static_cast<uint16_t>(header_size + extra_header_size);
112 }
97 113
98 if (max_handles_ > 0) { 114 if (max_handles_ > 0) {
99 #if defined(OS_WIN) 115 #if defined(OS_WIN)
100 handles_ = reinterpret_cast<HandleEntry*>(mutable_extra_header()); 116 handles_ = reinterpret_cast<HandleEntry*>(mutable_extra_header());
101 // Initialize all handles to invalid values. 117 // Initialize all handles to invalid values.
102 for (size_t i = 0; i < max_handles_; ++i) 118 for (size_t i = 0; i < max_handles_; ++i)
103 handles_[i].handle = base::win::HandleToUint32(INVALID_HANDLE_VALUE); 119 handles_[i].handle = base::win::HandleToUint32(INVALID_HANDLE_VALUE);
104 #elif defined(OS_MACOSX) && !defined(OS_IOS) 120 #elif defined(OS_MACOSX) && !defined(OS_IOS)
105 mach_ports_header_ = 121 mach_ports_header_ =
106 reinterpret_cast<MachPortsExtraHeader*>(mutable_extra_header()); 122 reinterpret_cast<MachPortsExtraHeader*>(mutable_extra_header());
107 mach_ports_header_->num_ports = 0; 123 mach_ports_header_->num_ports = 0;
108 // Initialize all handles to invalid values. 124 // Initialize all handles to invalid values.
109 for (size_t i = 0; i < max_handles_; ++i) { 125 for (size_t i = 0; i < max_handles_; ++i) {
110 mach_ports_header_->entries[i] = 126 mach_ports_header_->entries[i] =
111 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 127 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
112 } 128 }
113 #endif 129 #endif
114 } 130 }
115 } 131 }
116 132
117 Channel::Message::~Message() { 133 Channel::Message::~Message() {
118 base::AlignedFree(data_); 134 base::AlignedFree(data_);
119 } 135 }
120 136
121 // static 137 // static
122 Channel::MessagePtr Channel::Message::Deserialize(const void* data, 138 Channel::MessagePtr Channel::Message::Deserialize(const void* data,
123 size_t data_num_bytes) { 139 size_t data_num_bytes) {
124 if (data_num_bytes < sizeof(Header)) 140 if (data_num_bytes < sizeof(LegacyHeader))
125 return nullptr; 141 return nullptr;
126 142
127 const Header* header = reinterpret_cast<const Header*>(data); 143 const LegacyHeader* legacy_header =
128 if (header->num_bytes != data_num_bytes) { 144 reinterpret_cast<const LegacyHeader*>(data);
129 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes 145 if (legacy_header->num_bytes != data_num_bytes) {
146 DLOG(ERROR) << "Decoding invalid message: " << legacy_header->num_bytes
130 << " != " << data_num_bytes; 147 << " != " << data_num_bytes;
131 return nullptr; 148 return nullptr;
132 } 149 }
133 150
134 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 151 const Header* header = nullptr;
135 size_t payload_size = data_num_bytes - sizeof(Header); 152 if (legacy_header->message_type == MessageType::NORMAL)
136 const char* payload = static_cast<const char*>(data) + sizeof(Header); 153 header = reinterpret_cast<const Header*>(data);
137 #else 154
138 if (header->num_bytes < header->num_header_bytes || 155 uint32_t extra_header_size = 0;
139 header->num_header_bytes < sizeof(Header)) { 156 size_t payload_size = 0;
140 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < " 157 const char* payload = nullptr;
141 << header->num_header_bytes; 158 if (!header) {
142 return nullptr; 159 payload_size = data_num_bytes - sizeof(LegacyHeader);
160 payload = static_cast<const char*>(data) + sizeof(LegacyHeader);
161 } else {
162 if (header->num_bytes < header->num_header_bytes ||
163 header->num_header_bytes < sizeof(Header)) {
164 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < "
165 << header->num_header_bytes;
166 return nullptr;
167 }
168 extra_header_size = header->num_header_bytes - sizeof(Header);
169 payload_size = data_num_bytes - header->num_header_bytes;
170 payload = static_cast<const char*>(data) + header->num_header_bytes;
143 } 171 }
144 172
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) 173 #if defined(OS_WIN)
152 uint32_t max_handles = extra_header_size / sizeof(HandleEntry); 174 uint32_t max_handles = extra_header_size / sizeof(HandleEntry);
153 #elif defined(OS_MACOSX) && !defined(OS_IOS) 175 #elif defined(OS_MACOSX) && !defined(OS_IOS)
154 if (extra_header_size < sizeof(MachPortsExtraHeader)) { 176 if (extra_header_size > 0 &&
Ken Rockot(use gerrit already) 2017/02/28 16:58:32 I don't think this should ever be zero
Jay Civelli 2017/02/28 17:13:04 Yes, removed.
177 extra_header_size < sizeof(MachPortsExtraHeader)) {
155 DLOG(ERROR) << "Decoding invalid message: " << extra_header_size << " < " 178 DLOG(ERROR) << "Decoding invalid message: " << extra_header_size << " < "
156 << sizeof(MachPortsExtraHeader); 179 << sizeof(MachPortsExtraHeader);
157 return nullptr; 180 return nullptr;
158 } 181 }
159 uint32_t max_handles = (extra_header_size - sizeof(MachPortsExtraHeader)) / 182 uint32_t max_handles =
160 sizeof(MachPortsEntry); 183 extra_header_size == 0
Ken Rockot(use gerrit already) 2017/02/28 16:58:32 same here
Jay Civelli 2017/02/28 17:13:04 Removed.
184 ? 0
185 : (extra_header_size - sizeof(MachPortsExtraHeader)) /
186 sizeof(MachPortsEntry);
161 #else 187 #else
162 const uint32_t max_handles = 0; 188 const uint32_t max_handles = 0;
163 #endif // defined(OS_WIN) 189 #endif // defined(OS_WIN)
164 190
165 if (header->num_handles > max_handles || max_handles > kMaxAttachedHandles) { 191 const uint16_t num_handles =
166 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles 192 header ? header->num_handles : legacy_header->num_handles;
167 << " > " << max_handles; 193 if (num_handles > max_handles || max_handles > kMaxAttachedHandles) {
194 DLOG(ERROR) << "Decoding invalid message: " << num_handles << " > "
195 << max_handles;
168 return nullptr; 196 return nullptr;
169 } 197 }
170 198
171 MessagePtr message(new Message(payload_size, max_handles)); 199 MessagePtr message(
200 new Message(payload_size, max_handles, legacy_header->message_type));
172 DCHECK_EQ(message->data_num_bytes(), data_num_bytes); 201 DCHECK_EQ(message->data_num_bytes(), data_num_bytes);
173 202
174 // Copy all payload bytes. 203 // Copy all payload bytes.
175 if (payload_size) 204 if (payload_size)
176 memcpy(message->mutable_payload(), payload, payload_size); 205 memcpy(message->mutable_payload(), payload, payload_size);
177 206
178 #if !defined(MOJO_EDK_LEGACY_PROTOCOL) 207 if (header) {
179 DCHECK_EQ(message->extra_header_size(), extra_header_size); 208 DCHECK_EQ(message->extra_header_size(), extra_header_size);
180 DCHECK_EQ(message->header_->num_header_bytes, header->num_header_bytes); 209 DCHECK_EQ(message->header()->num_header_bytes, header->num_header_bytes);
181 210
182 if (message->extra_header_size()) { 211 if (message->extra_header_size()) {
183 // Copy extra header bytes. 212 // Copy extra header bytes.
184 memcpy(message->mutable_extra_header(), 213 memcpy(message->mutable_extra_header(),
185 static_cast<const char*>(data) + sizeof(Header), 214 static_cast<const char*>(data) + sizeof(Header),
186 message->extra_header_size()); 215 message->extra_header_size());
216 }
217 message->header()->num_handles = header->num_handles;
218 } else {
219 message->legacy_header()->num_handles = legacy_header->num_handles;
187 } 220 }
188 #endif
189 221
190 message->header_->num_handles = header->num_handles;
191 #if defined(OS_WIN) 222 #if defined(OS_WIN)
192 ScopedPlatformHandleVectorPtr handles( 223 ScopedPlatformHandleVectorPtr handles(new PlatformHandleVector(num_handles));
193 new PlatformHandleVector(header->num_handles)); 224 for (size_t i = 0; i < num_handles; i++) {
194 for (size_t i = 0; i < header->num_handles; i++) {
195 (*handles)[i].handle = 225 (*handles)[i].handle =
196 base::win::Uint32ToHandle(message->handles_[i].handle); 226 base::win::Uint32ToHandle(message->handles_[i].handle);
197 } 227 }
198 message->SetHandles(std::move(handles)); 228 message->SetHandles(std::move(handles));
199 #endif 229 #endif
200 230
201 return message; 231 return message;
202 } 232 }
203 233
234 const void* Channel::Message::extra_header() const {
235 DCHECK(!is_legacy_message());
236 return data_ + sizeof(Header);
237 }
238
239 void* Channel::Message::mutable_extra_header() {
240 DCHECK(!is_legacy_message());
241 return data_ + sizeof(Header);
242 }
243
244 size_t Channel::Message::extra_header_size() const {
245 return header()->num_header_bytes - sizeof(Header);
246 }
247
248 void* Channel::Message::mutable_payload() {
249 if (is_legacy_message())
250 return static_cast<void*>(legacy_header() + 1);
251 return data_ + header()->num_header_bytes;
252 }
253
254 const void* Channel::Message::payload() const {
255 if (is_legacy_message())
256 return static_cast<const void*>(legacy_header() + 1);
257 return data_ + header()->num_header_bytes;
258 }
259
204 size_t Channel::Message::payload_size() const { 260 size_t Channel::Message::payload_size() const {
205 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 261 if (is_legacy_message())
206 return header_->num_bytes - sizeof(Header); 262 return legacy_header()->num_bytes - sizeof(LegacyHeader);
207 #else 263 return size_ - header()->num_header_bytes;
208 return size_ - header_->num_header_bytes; 264 }
209 #endif 265
266 size_t Channel::Message::num_handles() const {
267 return is_legacy_message() ? legacy_header()->num_handles
268 : header()->num_handles;
269 }
270
271 bool Channel::Message::has_handles() const {
272 return (is_legacy_message() ? legacy_header()->num_handles
273 : header()->num_handles) > 0;
210 } 274 }
211 275
212 #if defined(OS_MACOSX) && !defined(OS_IOS) 276 #if defined(OS_MACOSX) && !defined(OS_IOS)
213 bool Channel::Message::has_mach_ports() const { 277 bool Channel::Message::has_mach_ports() const {
214 if (!has_handles()) 278 if (!has_handles())
215 return false; 279 return false;
216 280
217 for (const auto& handle : (*handle_vector_)) { 281 for (const auto& handle : (*handle_vector_)) {
218 if (handle.type == PlatformHandle::Type::MACH || 282 if (handle.type == PlatformHandle::Type::MACH ||
219 handle.type == PlatformHandle::Type::MACH_NAME) { 283 handle.type == PlatformHandle::Type::MACH_NAME) {
220 return true; 284 return true;
221 } 285 }
222 } 286 }
223 return false; 287 return false;
224 } 288 }
225 #endif 289 #endif
226 290
291 bool Channel::Message::is_legacy_message() const {
292 return legacy_header()->message_type == MessageType::NORMAL_LEGACY;
293 }
294
295 Channel::Message::LegacyHeader* Channel::Message::legacy_header() const {
296 return reinterpret_cast<LegacyHeader*>(data_);
297 }
298
299 Channel::Message::Header* Channel::Message::header() const {
300 DCHECK(!is_legacy_message());
301 return reinterpret_cast<Header*>(data_);
302 }
303
227 void Channel::Message::SetHandles(ScopedPlatformHandleVectorPtr new_handles) { 304 void Channel::Message::SetHandles(ScopedPlatformHandleVectorPtr new_handles) {
228 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 305 if (is_legacy_message()) {
229 // Old semantics for ChromeOS and Android 306 // Old semantics for ChromeOS and Android
230 if (header_->num_handles == 0) { 307 if (legacy_header()->num_handles == 0) {
231 CHECK(!new_handles || new_handles->size() == 0); 308 CHECK(!new_handles || new_handles->size() == 0);
309 return;
310 }
311 CHECK(new_handles && new_handles->size() == legacy_header()->num_handles);
312 std::swap(handle_vector_, new_handles);
232 return; 313 return;
233 } 314 }
234 CHECK(new_handles && new_handles->size() == header_->num_handles);
235 std::swap(handle_vector_, new_handles);
236 315
237 #else
238 if (max_handles_ == 0) { 316 if (max_handles_ == 0) {
239 CHECK(!new_handles || new_handles->size() == 0); 317 CHECK(!new_handles || new_handles->size() == 0);
240 return; 318 return;
241 } 319 }
242 320
243 CHECK(new_handles && new_handles->size() <= max_handles_); 321 CHECK(new_handles && new_handles->size() <= max_handles_);
244 header_->num_handles = static_cast<uint16_t>(new_handles->size()); 322 header()->num_handles = static_cast<uint16_t>(new_handles->size());
245 std::swap(handle_vector_, new_handles); 323 std::swap(handle_vector_, new_handles);
246 #if defined(OS_WIN) 324 #if defined(OS_WIN)
247 memset(handles_, 0, extra_header_size()); 325 memset(handles_, 0, extra_header_size());
248 for (size_t i = 0; i < handle_vector_->size(); i++) 326 for (size_t i = 0; i < handle_vector_->size(); i++)
249 handles_[i].handle = base::win::HandleToUint32((*handle_vector_)[i].handle); 327 handles_[i].handle = base::win::HandleToUint32((*handle_vector_)[i].handle);
250 #endif // defined(OS_WIN) 328 #endif // defined(OS_WIN)
251 #endif // defined(MOJO_EDK_LEGACY_PROTOCOL)
252 329
253 #if defined(OS_MACOSX) && !defined(OS_IOS) 330 #if defined(OS_MACOSX) && !defined(OS_IOS)
254 size_t mach_port_index = 0; 331 size_t mach_port_index = 0;
255 if (mach_ports_header_) { 332 if (mach_ports_header_) {
256 for (size_t i = 0; i < max_handles_; ++i) { 333 for (size_t i = 0; i < max_handles_; ++i) {
257 mach_ports_header_->entries[i] = 334 mach_ports_header_->entries[i] =
258 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 335 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
259 } 336 }
260 for (size_t i = 0; i < handle_vector_->size(); i++) { 337 for (size_t i = 0; i < handle_vector_->size(); i++) {
261 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH || 338 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH ||
(...skipping 11 matching lines...) Expand all
273 350
274 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() { 351 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() {
275 #if defined(OS_MACOSX) && !defined(OS_IOS) 352 #if defined(OS_MACOSX) && !defined(OS_IOS)
276 if (mach_ports_header_) { 353 if (mach_ports_header_) {
277 for (size_t i = 0; i < max_handles_; ++i) { 354 for (size_t i = 0; i < max_handles_; ++i) {
278 mach_ports_header_->entries[i] = 355 mach_ports_header_->entries[i] =
279 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 356 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
280 } 357 }
281 mach_ports_header_->num_ports = 0; 358 mach_ports_header_->num_ports = 0;
282 } 359 }
283 header_->num_handles = 0; 360 #endif
361 if (is_legacy_message())
362 legacy_header()->num_handles = 0;
363 else
364 header()->num_handles = 0;
284 return std::move(handle_vector_); 365 return std::move(handle_vector_);
285 #else
286 header_->num_handles = 0;
287 return std::move(handle_vector_);
288 #endif
289 } 366 }
290 367
291 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandlesForTransport() { 368 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandlesForTransport() {
292 #if defined(OS_WIN) 369 #if defined(OS_WIN)
293 // Not necessary on Windows. 370 // Not necessary on Windows.
294 NOTREACHED(); 371 NOTREACHED();
295 return nullptr; 372 return nullptr;
296 #elif defined(OS_MACOSX) && !defined(OS_IOS) 373 #elif defined(OS_MACOSX) && !defined(OS_IOS)
297 if (handle_vector_) { 374 if (handle_vector_) {
298 for (auto it = handle_vector_->begin(); it != handle_vector_->end(); ) { 375 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) 561 if (!required_capacity)
485 required_capacity = kReadBufferSize; 562 required_capacity = kReadBufferSize;
486 563
487 *buffer_capacity = required_capacity; 564 *buffer_capacity = required_capacity;
488 return read_buffer_->Reserve(required_capacity); 565 return read_buffer_->Reserve(required_capacity);
489 } 566 }
490 567
491 bool Channel::OnReadComplete(size_t bytes_read, size_t *next_read_size_hint) { 568 bool Channel::OnReadComplete(size_t bytes_read, size_t *next_read_size_hint) {
492 bool did_dispatch_message = false; 569 bool did_dispatch_message = false;
493 read_buffer_->Claim(bytes_read); 570 read_buffer_->Claim(bytes_read);
494 while (read_buffer_->num_occupied_bytes() >= sizeof(Message::Header)) { 571 while (read_buffer_->num_occupied_bytes() >= sizeof(Message::LegacyHeader)) {
495 // Ensure the occupied data is properly aligned. If it isn't, a SIGBUS could 572 // 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. 573 // 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. 574 // anything other than x86). Only re-align when necessary to avoid copies.
498 if (reinterpret_cast<uintptr_t>(read_buffer_->occupied_bytes()) % 575 if (!IsAlignedForChannelMessage(
499 kChannelMessageAlignment != 0) 576 reinterpret_cast<uintptr_t>(read_buffer_->occupied_bytes()))) {
500 read_buffer_->Realign(); 577 read_buffer_->Realign();
578 }
501 579
502 // We have at least enough data available for a MessageHeader. 580 // We have at least enough data available for a MessageHeader.
Ken Rockot(use gerrit already) 2017/02/28 16:58:32 nit: "LegacyHeader"
Jay Civelli 2017/02/28 17:13:04 Done.
503 const Message::Header* header = reinterpret_cast<const Message::Header*>( 581 const Message::LegacyHeader* legacy_header =
504 read_buffer_->occupied_bytes()); 582 reinterpret_cast<const Message::LegacyHeader*>(
505 if (header->num_bytes < sizeof(Message::Header) || 583 read_buffer_->occupied_bytes());
506 header->num_bytes > kMaxChannelMessageSize) { 584
507 LOG(ERROR) << "Invalid message size: " << header->num_bytes; 585 if (legacy_header->num_bytes < sizeof(Message::LegacyHeader) ||
586 legacy_header->num_bytes > kMaxChannelMessageSize) {
587 LOG(ERROR) << "Invalid message size: " << legacy_header->num_bytes;
508 return false; 588 return false;
509 } 589 }
510 590
511 if (read_buffer_->num_occupied_bytes() < header->num_bytes) { 591 if (read_buffer_->num_occupied_bytes() < legacy_header->num_bytes) {
512 // Not enough data available to read the full message. Hint to the 592 // 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. 593 // implementation that it should try reading the full size of the message.
514 *next_read_size_hint = 594 *next_read_size_hint =
515 header->num_bytes - read_buffer_->num_occupied_bytes(); 595 legacy_header->num_bytes - read_buffer_->num_occupied_bytes();
516 return true; 596 return true;
517 } 597 }
518 598
519 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 599 const Message::Header* header = nullptr;
600 if (legacy_header->message_type != Message::MessageType::NORMAL_LEGACY) {
601 header = reinterpret_cast<const Message::Header*>(legacy_header);
602 }
603
520 size_t extra_header_size = 0; 604 size_t extra_header_size = 0;
521 const void* extra_header = nullptr; 605 const void* extra_header = nullptr;
522 size_t payload_size = header->num_bytes - sizeof(Message::Header); 606 size_t payload_size = 0;
523 void* payload = payload_size ? const_cast<Message::Header*>(&header[1]) 607 void* payload = nullptr;
524 : nullptr; 608 if (header) {
525 #else 609 if (header->num_header_bytes < sizeof(Message::Header) ||
526 if (header->num_header_bytes < sizeof(Message::Header) || 610 header->num_header_bytes > header->num_bytes) {
527 header->num_header_bytes > header->num_bytes) { 611 LOG(ERROR) << "Invalid message header size: "
528 LOG(ERROR) << "Invalid message header size: " << header->num_header_bytes; 612 << header->num_header_bytes;
529 return false; 613 return false;
614 }
615 extra_header_size = header->num_header_bytes - sizeof(Message::Header);
616 extra_header = extra_header_size ? header + 1 : nullptr;
617 payload_size = header->num_bytes - header->num_header_bytes;
618 payload = payload_size
619 ? reinterpret_cast<Message::Header*>(
620 const_cast<char*>(read_buffer_->occupied_bytes()) +
621 header->num_header_bytes)
622 : nullptr;
623 } else {
624 payload_size = legacy_header->num_bytes - sizeof(Message::LegacyHeader);
625 payload = payload_size
626 ? const_cast<Message::LegacyHeader*>(&legacy_header[1])
627 : nullptr;
530 } 628 }
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 629
630 const uint16_t num_handles =
631 header ? header->num_handles : legacy_header->num_handles;
542 ScopedPlatformHandleVectorPtr handles; 632 ScopedPlatformHandleVectorPtr handles;
543 if (header->num_handles > 0) { 633 if (num_handles > 0) {
544 if (!GetReadPlatformHandles(header->num_handles, extra_header, 634 if (!GetReadPlatformHandles(num_handles, extra_header, extra_header_size,
545 extra_header_size, &handles)) { 635 &handles)) {
546 return false; 636 return false;
547 } 637 }
548 638
549 if (!handles) { 639 if (!handles) {
550 // Not enough handles available for this message. 640 // Not enough handles available for this message.
551 break; 641 break;
552 } 642 }
553 } 643 }
554 644
555 // We've got a complete message! Dispatch it and try another. 645 // We've got a complete message! Dispatch it and try another.
556 if (header->message_type != Message::Header::MessageType::NORMAL) { 646 if (legacy_header->message_type != Message::MessageType::NORMAL_LEGACY &&
557 if (!OnControlMessage(header->message_type, payload, payload_size, 647 legacy_header->message_type != Message::MessageType::NORMAL) {
648 if (!OnControlMessage(legacy_header->message_type, payload, payload_size,
558 std::move(handles))) { 649 std::move(handles))) {
559 return false; 650 return false;
560 } 651 }
561 did_dispatch_message = true; 652 did_dispatch_message = true;
562 } else if (delegate_) { 653 } else if (delegate_) {
563 delegate_->OnChannelMessage(payload, payload_size, std::move(handles)); 654 delegate_->OnChannelMessage(payload, payload_size, std::move(handles));
564 did_dispatch_message = true; 655 did_dispatch_message = true;
565 } 656 }
566 657
567 read_buffer_->Discard(header->num_bytes); 658 read_buffer_->Discard(legacy_header->num_bytes);
568 } 659 }
569 660
570 *next_read_size_hint = did_dispatch_message ? 0 : kReadBufferSize; 661 *next_read_size_hint = did_dispatch_message ? 0 : kReadBufferSize;
571 return true; 662 return true;
572 } 663 }
573 664
574 void Channel::OnError() { 665 void Channel::OnError() {
575 if (delegate_) 666 if (delegate_)
576 delegate_->OnChannelError(); 667 delegate_->OnChannelError();
577 } 668 }
578 669
579 bool Channel::OnControlMessage(Message::Header::MessageType message_type, 670 bool Channel::OnControlMessage(Message::MessageType message_type,
580 const void* payload, 671 const void* payload,
581 size_t payload_size, 672 size_t payload_size,
582 ScopedPlatformHandleVectorPtr handles) { 673 ScopedPlatformHandleVectorPtr handles) {
583 return false; 674 return false;
584 } 675 }
585 676
586 } // namespace edk 677 } // namespace edk
587 } // namespace mojo 678 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698