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
35namespace WebKit {
36
37RTCNetwork::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
52rtc::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
64auto 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
93void 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
112rtc::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
123auto 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
154void 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
170Optional<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
217void 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