1 | /* |
2 | * Copyright (C) 2016 Apple Inc. All rights reserved. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * 1. Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. |
9 | * 2. Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
15 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
17 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
19 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
20 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
21 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
23 | * THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #include "config.h" |
27 | #include "RTCNetwork.h" |
28 | |
29 | #if USE(LIBWEBRTC) |
30 | |
31 | #include "DataReference.h" |
32 | #include "WebCoreArgumentCoders.h" |
33 | #include <wtf/Optional.h> |
34 | |
35 | namespace WebKit { |
36 | |
37 | RTCNetwork::RTCNetwork(const rtc::Network& network) |
38 | : name(network.name()) |
39 | , description(network.description()) |
40 | , prefix { network.prefix() } |
41 | , prefixLength(network.prefix_length()) |
42 | , type(network.type()) |
43 | , id(network.id()) |
44 | , preference(network.preference()) |
45 | , active(network.active()) |
46 | , ignored(network.ignored()) |
47 | , scopeID(network.scope_id()) |
48 | , ips(network.GetIPs()) |
49 | { |
50 | } |
51 | |
52 | rtc::Network RTCNetwork::value() const |
53 | { |
54 | rtc::Network network(name.data(), description.data(), prefix.value, prefixLength, rtc::AdapterType(type)); |
55 | network.set_id(id); |
56 | network.set_preference(preference); |
57 | network.set_active(active); |
58 | network.set_ignored(ignored); |
59 | network.set_scope_id(scopeID); |
60 | network.SetIPs(ips, true); |
61 | return network; |
62 | } |
63 | |
64 | auto RTCNetwork::IPAddress::decode(IPC::Decoder& decoder) -> Optional<IPAddress> |
65 | { |
66 | IPAddress result; |
67 | int family; |
68 | if (!decoder.decode(family)) |
69 | return WTF::nullopt; |
70 | |
71 | ASSERT(family == AF_INET || family == AF_INET6 || family == AF_UNSPEC); |
72 | |
73 | if (family == AF_UNSPEC) |
74 | return result; |
75 | |
76 | IPC::DataReference data; |
77 | if (!decoder.decode(data)) |
78 | return WTF::nullopt; |
79 | |
80 | if (family == AF_INET) { |
81 | if (data.size() != sizeof(in_addr)) |
82 | return WTF::nullopt; |
83 | result.value = rtc::IPAddress(*reinterpret_cast<const in_addr*>(data.data())); |
84 | return result; |
85 | } |
86 | |
87 | if (data.size() != sizeof(in6_addr)) |
88 | return WTF::nullopt; |
89 | result.value = rtc::IPAddress(*reinterpret_cast<const in6_addr*>(data.data())); |
90 | return result; |
91 | } |
92 | |
93 | void RTCNetwork::IPAddress::encode(IPC::Encoder& encoder) const |
94 | { |
95 | auto family = value.family(); |
96 | ASSERT(family == AF_INET || family == AF_INET6 || family == AF_UNSPEC); |
97 | encoder << family; |
98 | |
99 | if (family == AF_UNSPEC) |
100 | return; |
101 | |
102 | if (family == AF_INET) { |
103 | auto address = value.ipv4_address(); |
104 | encoder << IPC::DataReference(reinterpret_cast<const uint8_t*>(&address), sizeof(address)); |
105 | return; |
106 | } |
107 | |
108 | auto address = value.ipv6_address(); |
109 | encoder << IPC::DataReference(reinterpret_cast<const uint8_t*>(&address), sizeof(address)); |
110 | } |
111 | |
112 | rtc::SocketAddress RTCNetwork::isolatedCopy(const rtc::SocketAddress& value) |
113 | { |
114 | rtc::SocketAddress copy; |
115 | copy.SetPort(value.port()); |
116 | copy.SetScopeID(value.scope_id()); |
117 | copy.SetIP(std::string(value.hostname().data(), value.hostname().size())); |
118 | if (!value.IsUnresolvedIP()) |
119 | copy.SetResolvedIP(value.ipaddr()); |
120 | return rtc::SocketAddress(copy); |
121 | } |
122 | |
123 | auto RTCNetwork::SocketAddress::decode(IPC::Decoder& decoder) -> Optional<SocketAddress> |
124 | { |
125 | SocketAddress result; |
126 | uint16_t port; |
127 | if (!decoder.decode(port)) |
128 | return WTF::nullopt; |
129 | int scopeId; |
130 | if (!decoder.decode(scopeId)) |
131 | return WTF::nullopt; |
132 | result.value.SetPort(port); |
133 | result.value.SetScopeID(scopeId); |
134 | |
135 | IPC::DataReference hostname; |
136 | if (!decoder.decode(hostname)) |
137 | return WTF::nullopt; |
138 | result.value.SetIP(std::string(reinterpret_cast<const char*>(hostname.data()), hostname.size())); |
139 | |
140 | bool isUnresolved; |
141 | if (!decoder.decode(isUnresolved)) |
142 | return WTF::nullopt; |
143 | if (isUnresolved) |
144 | return result; |
145 | |
146 | Optional<IPAddress> ipAddress; |
147 | decoder >> ipAddress; |
148 | if (!ipAddress) |
149 | return WTF::nullopt; |
150 | result.value.SetResolvedIP(ipAddress->value); |
151 | return result; |
152 | } |
153 | |
154 | void RTCNetwork::SocketAddress::encode(IPC::Encoder& encoder) const |
155 | { |
156 | encoder << value.port(); |
157 | encoder << value.scope_id(); |
158 | |
159 | auto hostname = value.hostname(); |
160 | encoder << IPC::DataReference(reinterpret_cast<const uint8_t*>(hostname.data()), hostname.length()); |
161 | |
162 | if (value.IsUnresolvedIP()) { |
163 | encoder << true; |
164 | return; |
165 | } |
166 | encoder << false; |
167 | encoder << RTCNetwork::IPAddress(value.ipaddr()); |
168 | } |
169 | |
170 | Optional<RTCNetwork> RTCNetwork::decode(IPC::Decoder& decoder) |
171 | { |
172 | RTCNetwork result; |
173 | IPC::DataReference name, description; |
174 | if (!decoder.decode(name)) |
175 | return WTF::nullopt; |
176 | result.name = std::string(reinterpret_cast<const char*>(name.data()), name.size()); |
177 | if (!decoder.decode(description)) |
178 | return WTF::nullopt; |
179 | result.description = std::string(reinterpret_cast<const char*>(description.data()), description.size()); |
180 | Optional<IPAddress> prefix; |
181 | decoder >> prefix; |
182 | if (!prefix) |
183 | return WTF::nullopt; |
184 | result.prefix = WTFMove(*prefix); |
185 | if (!decoder.decode(result.prefixLength)) |
186 | return WTF::nullopt; |
187 | if (!decoder.decode(result.type)) |
188 | return WTF::nullopt; |
189 | if (!decoder.decode(result.id)) |
190 | return WTF::nullopt; |
191 | if (!decoder.decode(result.preference)) |
192 | return WTF::nullopt; |
193 | if (!decoder.decode(result.active)) |
194 | return WTF::nullopt; |
195 | if (!decoder.decode(result.ignored)) |
196 | return WTF::nullopt; |
197 | if (!decoder.decode(result.scopeID)) |
198 | return WTF::nullopt; |
199 | |
200 | uint64_t length; |
201 | if (!decoder.decode(length)) |
202 | return WTF::nullopt; |
203 | result.ips.reserve(length); |
204 | for (size_t index = 0; index < length; ++index) { |
205 | Optional<IPAddress> address; |
206 | decoder >> address; |
207 | if (!address) |
208 | return WTF::nullopt; |
209 | int flags; |
210 | if (!decoder.decode(flags)) |
211 | return WTF::nullopt; |
212 | result.ips.push_back({ address->value, flags }); |
213 | } |
214 | return result; |
215 | } |
216 | |
217 | void RTCNetwork::encode(IPC::Encoder& encoder) const |
218 | { |
219 | encoder << IPC::DataReference(reinterpret_cast<const uint8_t*>(name.data()), name.length()); |
220 | encoder << IPC::DataReference(reinterpret_cast<const uint8_t*>(description.data()), description.length()); |
221 | encoder << prefix; |
222 | encoder << prefixLength; |
223 | encoder << type; |
224 | |
225 | encoder << id; |
226 | encoder << preference; |
227 | encoder << active; |
228 | encoder << ignored; |
229 | encoder << scopeID; |
230 | |
231 | encoder << (uint64_t)ips.size(); |
232 | for (auto& ip : ips) { |
233 | encoder << IPAddress { ip }; |
234 | encoder << ip.ipv6_flags(); |
235 | } |
236 | } |
237 | |
238 | } |
239 | |
240 | #endif // USE(LIBWEBRTC) |
241 | |