OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 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 | |
5 #ifndef MOJO_SYSTEM_TRANSPORT_DATA_H_ | |
6 #define MOJO_SYSTEM_TRANSPORT_DATA_H_ | |
7 | |
8 #include <stdint.h> | |
9 | |
10 #include <vector> | |
11 | |
12 #include "base/macros.h" | |
13 #include "base/memory/aligned_memory.h" | |
14 #include "base/memory/scoped_ptr.h" | |
15 #include "mojo/embedder/platform_handle.h" | |
16 #include "mojo/system/dispatcher.h" | |
17 #include "mojo/system/system_impl_export.h" | |
18 | |
19 namespace mojo { | |
20 namespace system { | |
21 | |
22 // This class is used by |MessageInTransit| to represent handles (|Dispatcher|s) | |
23 // in various stages of serialization. | |
24 // | |
25 // The stages are: | |
26 // - Before reaching |TransportData|: Turn |DispatcherTransport|s into | |
27 // |Dispatcher|s that are "owned" by (and attached to) a |MessageInTransit|. | |
28 // This invalidates the handles in the space of the sending application | |
29 // (and, e.g., if another thread is waiting on such a handle, it'll be | |
30 // notified of this invalidation). | |
31 // - Serialize these dispatchers into the |TransportData|: First, for each | |
32 // attached dispatcher, there's an entry in the |TransportData|'s "handle | |
33 // table", which points to a segment of (dispatcher-type-dependent) data. | |
34 // - During the serialization of the dispatchers, |PlatformHandle|s may be | |
35 // detached from the dispatchers and attached to the |TransportData|. | |
36 // - Before sending the |MessageInTransit|, including its main buffer and the | |
37 // |TransportData|'s buffer, the |Channel| sends any |PlatformHandle|s (in a | |
38 // platform-, and possibly sandobx-situation-, specific way) first. In doing | |
39 // so, it appends a "platform handle table" to the |TransportData| | |
40 // containing information about how to deserialize these |PlatformHandle|s. | |
41 // - Finally, at this point, to send the |MessageInTransit|, there only | |
42 // remains "inert" data: the |MessageInTransit|'s main buffer and data from | |
43 // the |TransportData|, consisting of the "handle table" (one entry for each | |
44 // attached dispatcher), dispatcher-type-specific data (one segment for each | |
45 // entry in the "handle table"), and the "platform handle table" (one entry | |
46 // for each attached |PlatformHandle|). | |
47 // | |
48 // To receive a message (|MessageInTransit|), the "reverse" happens: | |
49 // - On POSIX, receive and buffer |PlatformHandle|s (i.e., FDs), which were | |
50 // sent before the "inert" data. | |
51 // - Receive the "inert" data from the |MessageInTransit|. Examine its | |
52 // "platform handle table". On POSIX, match its entries with the buffered | |
53 // |PlatformHandle|s, which were previously received. On Windows, do what's | |
54 // necessary to obtain |PlatformHandle|s (e.g.: i. if the sender is fully | |
55 // trusted and able to duplicate handle into the receiver, then just pick | |
56 // out the |HANDLE| value; ii. if the receiver is fully trusted and able to | |
57 // duplicate handles from the receiver, do the |DuplicateHandle()|; iii. | |
58 // otherwise, talk to a broker to get handles). Reattach all the | |
59 // |PlatformHandle|s to the |MessageInTransit|. | |
60 // - For each entry in the "handle table", use serialized dispatcher data to | |
61 // reconstitute a dispatcher, taking ownership of associated | |
62 // |PlatformHandle|s (and detaching them). Attach these dispatchers to the | |
63 // |MessageInTransit|. | |
64 // - At this point, the |MessageInTransit| consists of its main buffer | |
65 // (primarily the data payload) and the attached dispatchers; the | |
66 // |TransportData| can be discarded. | |
67 // - When |MojoReadMessage()| is to give data to the application, attach the | |
68 // dispatchers to the (global, "core") handle table, getting handles; give | |
69 // the application the data payload and these handles. | |
70 // | |
71 // TODO(vtl): Everything above involving |PlatformHandle|s. | |
72 class MOJO_SYSTEM_IMPL_EXPORT TransportData { | |
73 public: | |
74 // The maximum size of a single serialized dispatcher. This must be a multiple | |
75 // of |kMessageAlignment|. | |
76 static const size_t kMaxSerializedDispatcherSize = 10000; | |
77 | |
78 // The maximum number of platform handles to attach for a single serialized | |
79 // dispatcher. | |
80 static const size_t kMaxSerializedDispatcherPlatformHandles = 2; | |
81 | |
82 TransportData( | |
83 scoped_ptr<std::vector<scoped_refptr<Dispatcher> > > dispatchers, | |
darin (slow to review)
2014/05/02 22:51:40
maybe a typedef would be helpful here
viettrungluu
2014/05/03 00:12:50
Good idea. I'll do it separately though, since app
| |
84 Channel* channel); | |
85 ~TransportData(); | |
86 | |
87 const void* buffer() const { return buffer_.get(); } | |
88 size_t buffer_size() const { return buffer_size_; } | |
89 | |
90 // Gets attached platform-specific handles; this may return null if there are | |
91 // none. Note that the caller may mutate the set of platform-specific handles. | |
92 std::vector<embedder::PlatformHandle>* platform_handles() { | |
93 return platform_handles_.get(); | |
94 } | |
95 | |
96 // Returns true if there are platform-specific handles attached. | |
97 bool has_platform_handles() const { | |
98 return platform_handles_ && !platform_handles_->empty(); | |
99 } | |
100 | |
101 // Receive-side functions: | |
102 | |
103 // Checks if the given buffer (from the "wire") looks like a valid | |
104 // |TransportData| buffer. (Should only be called if |buffer_size| is | |
105 // nonzero.) Returns null if valid, and a pointer to a human-readable error | |
106 // message (for debug/logging purposes) on error. Note: This checks the | |
107 // validity of the handle table entries (i.e., does range checking), but does | |
108 // not check that the validity of the actual serialized dispatcher | |
109 // information. | |
110 static const char* ValidateBuffer(const void* buffer, size_t buffer_size); | |
111 | |
112 // Deserializes dispatchers from the given (serialized) transport data buffer | |
113 // (typically from a |MessageInTransit::View|). |buffer| should be non-null | |
114 // and |buffer_size| should be nonzero. | |
115 static scoped_ptr<std::vector<scoped_refptr<Dispatcher> > > | |
116 DeserializeDispatchersFromBuffer(const void* buffer, | |
117 size_t buffer_size, | |
118 Channel* channel); | |
119 | |
120 private: | |
121 // To allow us to make compile-assertions about |Header|, etc. in the .cc | |
122 // file. | |
123 struct PrivateStructForCompileAsserts; | |
124 | |
125 // Header for the "secondary buffer"/"transport data". Must be a multiple of | |
126 // |MessageInTransit::kMessageAlignment| in size. Must be POD. | |
127 struct Header { | |
128 uint32_t num_handles; | |
129 // TODO(vtl): Not used yet: | |
130 uint32_t platform_handle_table_offset; | |
131 uint32_t num_platform_handles; | |
132 uint32_t unused; | |
133 }; | |
134 | |
135 struct HandleTableEntry { | |
136 int32_t type; // From |Dispatcher::Type| (|kTypeUnknown| for "invalid"). | |
137 uint32_t offset; // Relative to the start of the "secondary buffer". | |
138 uint32_t size; // (Not including any padding.) | |
139 uint32_t unused; | |
140 }; | |
141 | |
142 // The maximum possible size of a valid transport data buffer. | |
143 static const size_t kMaxBufferSize; | |
144 | |
145 // The maximum total number of platform handles that may be attached. | |
146 static const size_t kMaxPlatformHandles; | |
147 | |
148 size_t buffer_size_; | |
149 scoped_ptr<char, base::AlignedFreeDeleter> buffer_; // Never null. | |
150 | |
151 // Any platform-specific handles attached to this message (for inter-process | |
152 // transport). The vector (if any) owns the handles that it contains (and is | |
153 // responsible for closing them). | |
154 // TODO(vtl): With C++11, change it to a vector of |ScopedPlatformHandles|. | |
155 scoped_ptr<std::vector<embedder::PlatformHandle> > platform_handles_; | |
156 | |
157 DISALLOW_COPY_AND_ASSIGN(TransportData); | |
158 }; | |
159 | |
160 } // namespace system | |
161 } // namespace mojo | |
162 | |
163 #endif // MOJO_SYSTEM_TRANSPORT_DATA_H_ | |
OLD | NEW |