OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "ppapi/shared_impl/private/net_address_private_impl.h" | 5 #include "ppapi/shared_impl/private/net_address_private_impl.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 | 10 |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "ppapi/c/private/ppb_net_address_private.h" | 21 #include "ppapi/c/private/ppb_net_address_private.h" |
22 #include "ppapi/shared_impl/var.h" | 22 #include "ppapi/shared_impl/var.h" |
23 #include "ppapi/thunk/thunk.h" | 23 #include "ppapi/thunk/thunk.h" |
24 | 24 |
25 #if defined(OS_MACOSX) | 25 #if defined(OS_MACOSX) |
26 // This is a bit evil, but it's standard operating procedure for |s6_addr|.... | 26 // This is a bit evil, but it's standard operating procedure for |s6_addr|.... |
27 #define s6_addr16 __u6_addr.__u6_addr16 | 27 #define s6_addr16 __u6_addr.__u6_addr16 |
28 #endif | 28 #endif |
29 | 29 |
30 #if defined(OS_WIN) | 30 #if defined(OS_WIN) |
31 // The type of |sockaddr::sa_family|. | |
32 typedef ADDRESS_FAMILY sa_family_t; | |
33 | |
34 #define s6_addr16 u.Word | 31 #define s6_addr16 u.Word |
35 #endif | 32 #endif |
36 | 33 |
37 // The net address interface doesn't have a normal C -> C++ thunk since it | 34 // The net address interface doesn't have a normal C -> C++ thunk since it |
38 // doesn't actually have any proxy wrapping or associated objects; it's just a | 35 // doesn't actually have any proxy wrapping or associated objects; it's just a |
39 // call into base. So we implement the entire interface here, using the thunk | 36 // call into base. So we implement the entire interface here, using the thunk |
40 // namespace so it magically gets hooked up in the proper places. | 37 // namespace so it magically gets hooked up in the proper places. |
41 | 38 |
42 namespace ppapi { | 39 namespace ppapi { |
43 | 40 |
44 namespace { | 41 namespace { |
45 | 42 |
46 // This assert fails on OpenBSD for an unknown reason at the moment. | 43 // This assert fails on OpenBSD for an unknown reason at the moment. |
47 #if !defined(OS_OPENBSD) | 44 #if !defined(OS_OPENBSD) |
48 // Make sure the storage in |PP_NetAddress_Private| is big enough. (Do it here | 45 // Make sure the storage in |PP_NetAddress_Private| is big enough. (Do it here |
49 // since the data is opaque elsewhere.) | 46 // since the data is opaque elsewhere.) |
50 COMPILE_ASSERT(sizeof(reinterpret_cast<PP_NetAddress_Private*>(0)->data) >= | 47 COMPILE_ASSERT(sizeof(reinterpret_cast<PP_NetAddress_Private*>(0)->data) >= |
51 sizeof(sockaddr_storage), PP_NetAddress_Private_data_too_small); | 48 sizeof(sockaddr_storage), PP_NetAddress_Private_data_too_small); |
52 #endif | 49 #endif |
53 | 50 |
54 inline sa_family_t GetFamily(const PP_NetAddress_Private& addr) { | 51 uint16_t GetFamily(const PP_NetAddress_Private* addr) { |
55 return reinterpret_cast<const sockaddr*>(addr.data)->sa_family; | 52 return reinterpret_cast<const sockaddr*>(addr->data)->sa_family; |
| 53 } |
| 54 |
| 55 uint16_t GetPort(const PP_NetAddress_Private* addr) { |
| 56 if (GetFamily(addr) == AF_INET) { |
| 57 const sockaddr_in* a = reinterpret_cast<const sockaddr_in*>(addr->data); |
| 58 return ntohs(a->sin_port); |
| 59 } else if (GetFamily(addr) == AF_INET6) { |
| 60 const sockaddr_in6* a = reinterpret_cast<const sockaddr_in6*>(addr->data); |
| 61 return ntohs(a->sin6_port); |
| 62 } |
| 63 |
| 64 return 0; |
| 65 } |
| 66 |
| 67 PP_Bool GetAddress(const PP_NetAddress_Private* addr, |
| 68 void* address, |
| 69 uint16_t address_size) { |
| 70 if (GetFamily(addr) == AF_INET) { |
| 71 const sockaddr_in* a = reinterpret_cast<const sockaddr_in*>(addr->data); |
| 72 if (address_size >= sizeof(a->sin_addr.s_addr)) { |
| 73 memcpy(address, &(a->sin_addr.s_addr), sizeof(a->sin_addr.s_addr)); |
| 74 return PP_TRUE; |
| 75 } |
| 76 } else if (GetFamily(addr) == AF_INET6) { |
| 77 const sockaddr_in6* a = reinterpret_cast<const sockaddr_in6*>(addr->data); |
| 78 if (address_size >= sizeof(a->sin6_addr.s6_addr)) { |
| 79 memcpy(address, &(a->sin6_addr.s6_addr), sizeof(a->sin6_addr.s6_addr)); |
| 80 return PP_TRUE; |
| 81 } |
| 82 } |
| 83 |
| 84 return PP_FALSE; |
56 } | 85 } |
57 | 86 |
58 PP_Bool AreHostsEqual(const PP_NetAddress_Private* addr1, | 87 PP_Bool AreHostsEqual(const PP_NetAddress_Private* addr1, |
59 const PP_NetAddress_Private* addr2) { | 88 const PP_NetAddress_Private* addr2) { |
60 if (!NetAddressPrivateImpl::ValidateNetAddress(*addr1) || | 89 if (!NetAddressPrivateImpl::ValidateNetAddress(*addr1) || |
61 !NetAddressPrivateImpl::ValidateNetAddress(*addr2)) | 90 !NetAddressPrivateImpl::ValidateNetAddress(*addr2)) |
62 return PP_FALSE; | 91 return PP_FALSE; |
63 | 92 |
64 if (GetFamily(*addr1) != GetFamily(*addr2)) | 93 if (GetFamily(addr1) != GetFamily(addr2)) |
65 return PP_FALSE; | 94 return PP_FALSE; |
66 | 95 |
67 if (GetFamily(*addr1) == AF_INET) { | 96 if (GetFamily(addr1) == AF_INET) { |
68 const sockaddr_in* a1 = reinterpret_cast<const sockaddr_in*>(addr1->data); | 97 const sockaddr_in* a1 = reinterpret_cast<const sockaddr_in*>(addr1->data); |
69 const sockaddr_in* a2 = reinterpret_cast<const sockaddr_in*>(addr2->data); | 98 const sockaddr_in* a2 = reinterpret_cast<const sockaddr_in*>(addr2->data); |
70 return PP_FromBool(a1->sin_addr.s_addr == a2->sin_addr.s_addr); | 99 return PP_FromBool(a1->sin_addr.s_addr == a2->sin_addr.s_addr); |
71 } | 100 } |
72 | 101 |
73 if (GetFamily(*addr1) == AF_INET6) { | 102 if (GetFamily(addr1) == AF_INET6) { |
74 const sockaddr_in6* a1 = reinterpret_cast<const sockaddr_in6*>(addr1->data); | 103 const sockaddr_in6* a1 = reinterpret_cast<const sockaddr_in6*>(addr1->data); |
75 const sockaddr_in6* a2 = reinterpret_cast<const sockaddr_in6*>(addr2->data); | 104 const sockaddr_in6* a2 = reinterpret_cast<const sockaddr_in6*>(addr2->data); |
76 return PP_FromBool(a1->sin6_flowinfo == a2->sin6_flowinfo && | 105 return PP_FromBool(a1->sin6_flowinfo == a2->sin6_flowinfo && |
77 memcmp(&a1->sin6_addr, &a2->sin6_addr, | 106 memcmp(&a1->sin6_addr, &a2->sin6_addr, |
78 sizeof(a1->sin6_addr)) == 0 && | 107 sizeof(a1->sin6_addr)) == 0 && |
79 a1->sin6_scope_id == a2->sin6_scope_id); | 108 a1->sin6_scope_id == a2->sin6_scope_id); |
80 } | 109 } |
81 | 110 |
82 return PP_FALSE; | 111 return PP_FALSE; |
83 } | 112 } |
84 | 113 |
85 PP_Bool AreEqual(const PP_NetAddress_Private* addr1, | 114 PP_Bool AreEqual(const PP_NetAddress_Private* addr1, |
86 const PP_NetAddress_Private* addr2) { | 115 const PP_NetAddress_Private* addr2) { |
87 // |AreHostsEqual()| will also validate the addresses and return false if | 116 // |AreHostsEqual()| will also validate the addresses and return false if |
88 // either is invalid. | 117 // either is invalid. |
89 if (!AreHostsEqual(addr1, addr2)) | 118 if (!AreHostsEqual(addr1, addr2)) |
90 return PP_FALSE; | 119 return PP_FALSE; |
91 | 120 |
92 // Note: Here, we know that |addr1| and |addr2| have the same family. | 121 // Note: Here, we know that |addr1| and |addr2| have the same family. |
93 if (GetFamily(*addr1) == AF_INET) { | 122 if (GetFamily(addr1) == AF_INET) { |
94 const sockaddr_in* a1 = reinterpret_cast<const sockaddr_in*>(addr1->data); | 123 const sockaddr_in* a1 = reinterpret_cast<const sockaddr_in*>(addr1->data); |
95 const sockaddr_in* a2 = reinterpret_cast<const sockaddr_in*>(addr2->data); | 124 const sockaddr_in* a2 = reinterpret_cast<const sockaddr_in*>(addr2->data); |
96 return PP_FromBool(a1->sin_port == a2->sin_port); | 125 return PP_FromBool(a1->sin_port == a2->sin_port); |
97 } | 126 } |
98 | 127 |
99 if (GetFamily(*addr1) == AF_INET6) { | 128 if (GetFamily(addr1) == AF_INET6) { |
100 const sockaddr_in6* a1 = reinterpret_cast<const sockaddr_in6*>(addr1->data); | 129 const sockaddr_in6* a1 = reinterpret_cast<const sockaddr_in6*>(addr1->data); |
101 const sockaddr_in6* a2 = reinterpret_cast<const sockaddr_in6*>(addr2->data); | 130 const sockaddr_in6* a2 = reinterpret_cast<const sockaddr_in6*>(addr2->data); |
102 return PP_FromBool(a1->sin6_port == a2->sin6_port); | 131 return PP_FromBool(a1->sin6_port == a2->sin6_port); |
103 } | 132 } |
104 | 133 |
105 return PP_FALSE; | 134 return PP_FALSE; |
106 } | 135 } |
107 | 136 |
108 #if defined(OS_WIN) || defined(OS_MACOSX) | 137 #if defined(OS_WIN) || defined(OS_MACOSX) |
109 std::string ConvertIPv4AddressToString(const sockaddr_in* a, | 138 std::string ConvertIPv4AddressToString(const sockaddr_in* a, |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 PP_Bool include_port) { | 229 PP_Bool include_port) { |
201 if (!NetAddressPrivateImpl::ValidateNetAddress(*addr)) | 230 if (!NetAddressPrivateImpl::ValidateNetAddress(*addr)) |
202 return PP_MakeUndefined(); | 231 return PP_MakeUndefined(); |
203 | 232 |
204 #if defined(OS_WIN) || defined(OS_MACOSX) | 233 #if defined(OS_WIN) || defined(OS_MACOSX) |
205 // On Windows, |NetAddressToString()| doesn't work in the sandbox. On Mac, | 234 // On Windows, |NetAddressToString()| doesn't work in the sandbox. On Mac, |
206 // the output isn't consistent with RFC 5952, at least on Mac OS 10.6: | 235 // the output isn't consistent with RFC 5952, at least on Mac OS 10.6: |
207 // |getnameinfo()| collapses length-one runs of zeros (and also doesn't | 236 // |getnameinfo()| collapses length-one runs of zeros (and also doesn't |
208 // display the scope). | 237 // display the scope). |
209 // TODO(viettrungluu): Consider switching to this on Linux. | 238 // TODO(viettrungluu): Consider switching to this on Linux. |
210 switch (GetFamily(*addr)) { | 239 switch (GetFamily(addr)) { |
211 case AF_INET: { | 240 case AF_INET: { |
212 const sockaddr_in* a = reinterpret_cast<const sockaddr_in*>(addr->data); | 241 const sockaddr_in* a = reinterpret_cast<const sockaddr_in*>(addr->data); |
213 return StringVar::StringToPPVar( | 242 return StringVar::StringToPPVar( |
214 ConvertIPv4AddressToString(a, !!include_port)); | 243 ConvertIPv4AddressToString(a, !!include_port)); |
215 } | 244 } |
216 case AF_INET6: { | 245 case AF_INET6: { |
217 const sockaddr_in6* a = reinterpret_cast<const sockaddr_in6*>(addr->data); | 246 const sockaddr_in6* a = reinterpret_cast<const sockaddr_in6*>(addr->data); |
218 return StringVar::StringToPPVar( | 247 return StringVar::StringToPPVar( |
219 ConvertIPv6AddressToString(a, !!include_port)); | 248 ConvertIPv6AddressToString(a, !!include_port)); |
220 } | 249 } |
(...skipping 11 matching lines...) Expand all Loading... |
232 return StringVar::StringToPPVar(description); | 261 return StringVar::StringToPPVar(description); |
233 #endif | 262 #endif |
234 } | 263 } |
235 | 264 |
236 PP_Bool ReplacePort(const struct PP_NetAddress_Private* src_addr, | 265 PP_Bool ReplacePort(const struct PP_NetAddress_Private* src_addr, |
237 uint16_t port, | 266 uint16_t port, |
238 struct PP_NetAddress_Private* dest_addr) { | 267 struct PP_NetAddress_Private* dest_addr) { |
239 if (!NetAddressPrivateImpl::ValidateNetAddress(*src_addr)) | 268 if (!NetAddressPrivateImpl::ValidateNetAddress(*src_addr)) |
240 return PP_FALSE; | 269 return PP_FALSE; |
241 | 270 |
242 if (GetFamily(*src_addr) == AF_INET) { | 271 if (GetFamily(src_addr) == AF_INET) { |
243 memmove(dest_addr, src_addr, sizeof(*src_addr)); | 272 memmove(dest_addr, src_addr, sizeof(*src_addr)); |
244 reinterpret_cast<sockaddr_in*>(dest_addr->data)->sin_port = htons(port); | 273 reinterpret_cast<sockaddr_in*>(dest_addr->data)->sin_port = htons(port); |
245 return PP_TRUE; | 274 return PP_TRUE; |
246 } | 275 } |
247 | 276 |
248 if (GetFamily(*src_addr) == AF_INET6) { | 277 if (GetFamily(src_addr) == AF_INET6) { |
249 memmove(dest_addr, src_addr, sizeof(*src_addr)); | 278 memmove(dest_addr, src_addr, sizeof(*src_addr)); |
250 reinterpret_cast<sockaddr_in6*>(dest_addr->data)->sin6_port = htons(port); | 279 reinterpret_cast<sockaddr_in6*>(dest_addr->data)->sin6_port = htons(port); |
251 return PP_TRUE; | 280 return PP_TRUE; |
252 } | 281 } |
253 | 282 |
254 return PP_FALSE; | 283 return PP_FALSE; |
255 } | 284 } |
256 | 285 |
257 void GetAnyAddress(PP_Bool is_ipv6, PP_NetAddress_Private* addr) { | 286 void GetAnyAddress(PP_Bool is_ipv6, PP_NetAddress_Private* addr) { |
258 memset(addr->data, 0, arraysize(addr->data) * sizeof(addr->data[0])); | 287 memset(addr->data, 0, arraysize(addr->data) * sizeof(addr->data[0])); |
259 if (is_ipv6) { | 288 if (is_ipv6) { |
260 sockaddr_in6* a = reinterpret_cast<sockaddr_in6*>(addr->data); | 289 sockaddr_in6* a = reinterpret_cast<sockaddr_in6*>(addr->data); |
261 addr->size = sizeof(*a); | 290 addr->size = sizeof(*a); |
262 a->sin6_family = AF_INET6; | 291 a->sin6_family = AF_INET6; |
263 a->sin6_addr = in6addr_any; | 292 a->sin6_addr = in6addr_any; |
264 } else { | 293 } else { |
265 sockaddr_in* a = reinterpret_cast<sockaddr_in*>(addr->data); | 294 sockaddr_in* a = reinterpret_cast<sockaddr_in*>(addr->data); |
266 addr->size = sizeof(*a); | 295 addr->size = sizeof(*a); |
267 a->sin_family = AF_INET; | 296 a->sin_family = AF_INET; |
268 a->sin_addr.s_addr = INADDR_ANY; | 297 a->sin_addr.s_addr = INADDR_ANY; |
269 } | 298 } |
270 } | 299 } |
271 | 300 |
272 const PPB_NetAddress_Private net_address_private_interface = { | 301 const PPB_NetAddress_Private_0_1 net_address_private_interface_0_1 = { |
273 &AreEqual, | 302 &AreEqual, |
274 &AreHostsEqual, | 303 &AreHostsEqual, |
275 &Describe, | 304 &Describe, |
276 &ReplacePort, | 305 &ReplacePort, |
277 &GetAnyAddress | 306 &GetAnyAddress |
278 }; | 307 }; |
279 | 308 |
| 309 const PPB_NetAddress_Private_1_0 net_address_private_interface_1_0 = { |
| 310 &AreEqual, |
| 311 &AreHostsEqual, |
| 312 &Describe, |
| 313 &ReplacePort, |
| 314 &GetAnyAddress, |
| 315 &GetFamily, |
| 316 &GetPort, |
| 317 &GetAddress |
| 318 }; |
| 319 |
280 } // namespace | 320 } // namespace |
281 | 321 |
282 namespace thunk { | 322 namespace thunk { |
283 | 323 |
284 PPAPI_THUNK_EXPORT const PPB_NetAddress_Private_0_1* | 324 PPAPI_THUNK_EXPORT const PPB_NetAddress_Private_0_1* |
285 GetPPB_NetAddress_Private_0_1_Thunk() { | 325 GetPPB_NetAddress_Private_0_1_Thunk() { |
286 return &net_address_private_interface; | 326 return &net_address_private_interface_0_1; |
| 327 } |
| 328 |
| 329 PPAPI_THUNK_EXPORT const PPB_NetAddress_Private_1_0* |
| 330 GetPPB_NetAddress_Private_1_0_Thunk() { |
| 331 return &net_address_private_interface_1_0; |
287 } | 332 } |
288 | 333 |
289 } // namespace thunk | 334 } // namespace thunk |
290 | 335 |
291 // static | 336 // static |
292 const PP_NetAddress_Private NetAddressPrivateImpl::kInvalidNetAddress = { 0 }; | 337 const PP_NetAddress_Private NetAddressPrivateImpl::kInvalidNetAddress = { 0 }; |
293 | 338 |
294 // static | 339 // static |
295 bool NetAddressPrivateImpl::ValidateNetAddress( | 340 bool NetAddressPrivateImpl::ValidateNetAddress( |
296 const PP_NetAddress_Private& addr) { | 341 const PP_NetAddress_Private& addr) { |
297 if (addr.size < sizeof(reinterpret_cast<sockaddr*>(0)->sa_family)) | 342 if (addr.size < sizeof(reinterpret_cast<sockaddr*>(0)->sa_family)) |
298 return false; | 343 return false; |
299 | 344 |
300 // TODO(viettrungluu): more careful validation? | 345 // TODO(viettrungluu): more careful validation? |
301 // Just do a size check for AF_INET. | 346 // Just do a size check for AF_INET. |
302 if (GetFamily(addr) == AF_INET && addr.size >= sizeof(sockaddr_in)) | 347 if (GetFamily(&addr) == AF_INET && addr.size >= sizeof(sockaddr_in)) |
303 return true; | 348 return true; |
304 | 349 |
305 // Ditto for AF_INET6. | 350 // Ditto for AF_INET6. |
306 if (GetFamily(addr) == AF_INET6 && addr.size >= sizeof(sockaddr_in6)) | 351 if (GetFamily(&addr) == AF_INET6 && addr.size >= sizeof(sockaddr_in6)) |
307 return true; | 352 return true; |
308 | 353 |
309 // Reject everything else. | 354 // Reject everything else. |
310 return false; | 355 return false; |
311 } | 356 } |
312 | 357 |
313 // static | 358 // static |
314 bool NetAddressPrivateImpl::SockaddrToNetAddress( | 359 bool NetAddressPrivateImpl::SockaddrToNetAddress( |
315 const sockaddr* sa, | 360 const sockaddr* sa, |
316 uint32_t sa_length, | 361 uint32_t sa_length, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 net::IPEndPoint ip_end_point; | 414 net::IPEndPoint ip_end_point; |
370 if (!NetAddressToIPEndPoint(net_addr, &ip_end_point)) | 415 if (!NetAddressToIPEndPoint(net_addr, &ip_end_point)) |
371 return false; | 416 return false; |
372 | 417 |
373 *address_list = net::AddressList::CreateFromIPAddress(ip_end_point.address(), | 418 *address_list = net::AddressList::CreateFromIPAddress(ip_end_point.address(), |
374 ip_end_point.port()); | 419 ip_end_point.port()); |
375 return true; | 420 return true; |
376 } | 421 } |
377 | 422 |
378 } // namespace ppapi | 423 } // namespace ppapi |
OLD | NEW |