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 |
31 #define s6_addr16 u.Word | 34 #define s6_addr16 u.Word |
32 #endif | 35 #endif |
33 | 36 |
34 // The net address interface doesn't have a normal C -> C++ thunk since it | 37 // The net address interface doesn't have a normal C -> C++ thunk since it |
35 // doesn't actually have any proxy wrapping or associated objects; it's just a | 38 // doesn't actually have any proxy wrapping or associated objects; it's just a |
36 // call into base. So we implement the entire interface here, using the thunk | 39 // call into base. So we implement the entire interface here, using the thunk |
37 // namespace so it magically gets hooked up in the proper places. | 40 // namespace so it magically gets hooked up in the proper places. |
38 | 41 |
39 namespace ppapi { | 42 namespace ppapi { |
40 | 43 |
41 namespace { | 44 namespace { |
42 | 45 |
43 // This assert fails on OpenBSD for an unknown reason at the moment. | 46 // This assert fails on OpenBSD for an unknown reason at the moment. |
44 #if !defined(OS_OPENBSD) | 47 #if !defined(OS_OPENBSD) |
45 // Make sure the storage in |PP_NetAddress_Private| is big enough. (Do it here | 48 // Make sure the storage in |PP_NetAddress_Private| is big enough. (Do it here |
46 // since the data is opaque elsewhere.) | 49 // since the data is opaque elsewhere.) |
47 COMPILE_ASSERT(sizeof(reinterpret_cast<PP_NetAddress_Private*>(0)->data) >= | 50 COMPILE_ASSERT(sizeof(reinterpret_cast<PP_NetAddress_Private*>(0)->data) >= |
48 sizeof(sockaddr_storage), PP_NetAddress_Private_data_too_small); | 51 sizeof(sockaddr_storage), PP_NetAddress_Private_data_too_small); |
49 #endif | 52 #endif |
50 | 53 |
51 uint16_t GetFamily(const PP_NetAddress_Private* addr) { | 54 sa_family_t GetFamilyInternal(const PP_NetAddress_Private* addr) { |
52 return reinterpret_cast<const sockaddr*>(addr->data)->sa_family; | 55 return reinterpret_cast<const sockaddr*>(addr->data)->sa_family; |
53 } | 56 } |
54 | 57 |
| 58 PP_NetAddressFamily_Private GetFamily(const PP_NetAddress_Private* addr) { |
| 59 switch (GetFamilyInternal(addr)) { |
| 60 case AF_INET: |
| 61 return PP_NETADDRESSFAMILY_IPV4; |
| 62 case AF_INET6: |
| 63 return PP_NETADDRESSFAMILY_IPV6; |
| 64 default: |
| 65 return PP_NETADDRESSFAMILY_UNSPECIFIED; |
| 66 } |
| 67 } |
| 68 |
55 uint16_t GetPort(const PP_NetAddress_Private* addr) { | 69 uint16_t GetPort(const PP_NetAddress_Private* addr) { |
56 if (GetFamily(addr) == AF_INET) { | 70 switch (GetFamilyInternal(addr)) { |
57 const sockaddr_in* a = reinterpret_cast<const sockaddr_in*>(addr->data); | 71 case AF_INET: { |
58 return ntohs(a->sin_port); | 72 const sockaddr_in* a = reinterpret_cast<const sockaddr_in*>(addr->data); |
59 } else if (GetFamily(addr) == AF_INET6) { | 73 return ntohs(a->sin_port); |
60 const sockaddr_in6* a = reinterpret_cast<const sockaddr_in6*>(addr->data); | 74 } |
61 return ntohs(a->sin6_port); | 75 case AF_INET6: { |
| 76 const sockaddr_in6* a = reinterpret_cast<const sockaddr_in6*>(addr->data); |
| 77 return ntohs(a->sin6_port); |
| 78 } |
| 79 default: |
| 80 return 0; |
62 } | 81 } |
63 | |
64 return 0; | |
65 } | 82 } |
66 | 83 |
67 PP_Bool GetAddress(const PP_NetAddress_Private* addr, | 84 PP_Bool GetAddress(const PP_NetAddress_Private* addr, |
68 void* address, | 85 void* address, |
69 uint16_t address_size) { | 86 uint16_t address_size) { |
70 if (GetFamily(addr) == AF_INET) { | 87 switch (GetFamilyInternal(addr)) { |
71 const sockaddr_in* a = reinterpret_cast<const sockaddr_in*>(addr->data); | 88 case AF_INET: { |
72 if (address_size >= sizeof(a->sin_addr.s_addr)) { | 89 const sockaddr_in* a = reinterpret_cast<const sockaddr_in*>(addr->data); |
73 memcpy(address, &(a->sin_addr.s_addr), sizeof(a->sin_addr.s_addr)); | 90 if (address_size >= sizeof(a->sin_addr.s_addr)) { |
74 return PP_TRUE; | 91 memcpy(address, &(a->sin_addr.s_addr), sizeof(a->sin_addr.s_addr)); |
| 92 return PP_TRUE; |
| 93 } |
| 94 break; |
75 } | 95 } |
76 } else if (GetFamily(addr) == AF_INET6) { | 96 case AF_INET6: { |
77 const sockaddr_in6* a = reinterpret_cast<const sockaddr_in6*>(addr->data); | 97 const sockaddr_in6* a = reinterpret_cast<const sockaddr_in6*>(addr->data); |
78 if (address_size >= sizeof(a->sin6_addr.s6_addr)) { | 98 if (address_size >= sizeof(a->sin6_addr.s6_addr)) { |
79 memcpy(address, &(a->sin6_addr.s6_addr), sizeof(a->sin6_addr.s6_addr)); | 99 memcpy(address, &(a->sin6_addr.s6_addr), sizeof(a->sin6_addr.s6_addr)); |
80 return PP_TRUE; | 100 return PP_TRUE; |
| 101 } |
| 102 break; |
81 } | 103 } |
| 104 default: |
| 105 break; |
82 } | 106 } |
83 | 107 |
84 return PP_FALSE; | 108 return PP_FALSE; |
85 } | 109 } |
86 | 110 |
87 PP_Bool AreHostsEqual(const PP_NetAddress_Private* addr1, | 111 PP_Bool AreHostsEqual(const PP_NetAddress_Private* addr1, |
88 const PP_NetAddress_Private* addr2) { | 112 const PP_NetAddress_Private* addr2) { |
89 if (!NetAddressPrivateImpl::ValidateNetAddress(*addr1) || | 113 if (!NetAddressPrivateImpl::ValidateNetAddress(*addr1) || |
90 !NetAddressPrivateImpl::ValidateNetAddress(*addr2)) | 114 !NetAddressPrivateImpl::ValidateNetAddress(*addr2)) |
91 return PP_FALSE; | 115 return PP_FALSE; |
92 | 116 |
93 if (GetFamily(addr1) != GetFamily(addr2)) | 117 sa_family_t addr1_family = GetFamilyInternal(addr1); |
| 118 if (addr1_family != GetFamilyInternal(addr2)) |
94 return PP_FALSE; | 119 return PP_FALSE; |
95 | 120 |
96 if (GetFamily(addr1) == AF_INET) { | 121 switch (addr1_family) { |
97 const sockaddr_in* a1 = reinterpret_cast<const sockaddr_in*>(addr1->data); | 122 case AF_INET: { |
98 const sockaddr_in* a2 = reinterpret_cast<const sockaddr_in*>(addr2->data); | 123 const sockaddr_in* a1 = reinterpret_cast<const sockaddr_in*>(addr1->data); |
99 return PP_FromBool(a1->sin_addr.s_addr == a2->sin_addr.s_addr); | 124 const sockaddr_in* a2 = reinterpret_cast<const sockaddr_in*>(addr2->data); |
| 125 return PP_FromBool(a1->sin_addr.s_addr == a2->sin_addr.s_addr); |
| 126 } |
| 127 case AF_INET6: { |
| 128 const sockaddr_in6* a1 = |
| 129 reinterpret_cast<const sockaddr_in6*>(addr1->data); |
| 130 const sockaddr_in6* a2 = |
| 131 reinterpret_cast<const sockaddr_in6*>(addr2->data); |
| 132 return PP_FromBool(a1->sin6_flowinfo == a2->sin6_flowinfo && |
| 133 memcmp(&a1->sin6_addr, &a2->sin6_addr, |
| 134 sizeof(a1->sin6_addr)) == 0 && |
| 135 a1->sin6_scope_id == a2->sin6_scope_id); |
| 136 } |
| 137 default: |
| 138 return PP_FALSE; |
100 } | 139 } |
101 | |
102 if (GetFamily(addr1) == AF_INET6) { | |
103 const sockaddr_in6* a1 = reinterpret_cast<const sockaddr_in6*>(addr1->data); | |
104 const sockaddr_in6* a2 = reinterpret_cast<const sockaddr_in6*>(addr2->data); | |
105 return PP_FromBool(a1->sin6_flowinfo == a2->sin6_flowinfo && | |
106 memcmp(&a1->sin6_addr, &a2->sin6_addr, | |
107 sizeof(a1->sin6_addr)) == 0 && | |
108 a1->sin6_scope_id == a2->sin6_scope_id); | |
109 } | |
110 | |
111 return PP_FALSE; | |
112 } | 140 } |
113 | 141 |
114 PP_Bool AreEqual(const PP_NetAddress_Private* addr1, | 142 PP_Bool AreEqual(const PP_NetAddress_Private* addr1, |
115 const PP_NetAddress_Private* addr2) { | 143 const PP_NetAddress_Private* addr2) { |
116 // |AreHostsEqual()| will also validate the addresses and return false if | 144 // |AreHostsEqual()| will also validate the addresses and return false if |
117 // either is invalid. | 145 // either is invalid. |
118 if (!AreHostsEqual(addr1, addr2)) | 146 if (!AreHostsEqual(addr1, addr2)) |
119 return PP_FALSE; | 147 return PP_FALSE; |
120 | 148 |
121 // Note: Here, we know that |addr1| and |addr2| have the same family. | 149 // Note: Here, we know that |addr1| and |addr2| have the same family. |
122 if (GetFamily(addr1) == AF_INET) { | 150 switch (GetFamilyInternal(addr1)) { |
123 const sockaddr_in* a1 = reinterpret_cast<const sockaddr_in*>(addr1->data); | 151 case AF_INET: { |
124 const sockaddr_in* a2 = reinterpret_cast<const sockaddr_in*>(addr2->data); | 152 const sockaddr_in* a1 = reinterpret_cast<const sockaddr_in*>(addr1->data); |
125 return PP_FromBool(a1->sin_port == a2->sin_port); | 153 const sockaddr_in* a2 = reinterpret_cast<const sockaddr_in*>(addr2->data); |
| 154 return PP_FromBool(a1->sin_port == a2->sin_port); |
| 155 } |
| 156 case AF_INET6: { |
| 157 const sockaddr_in6* a1 = |
| 158 reinterpret_cast<const sockaddr_in6*>(addr1->data); |
| 159 const sockaddr_in6* a2 = |
| 160 reinterpret_cast<const sockaddr_in6*>(addr2->data); |
| 161 return PP_FromBool(a1->sin6_port == a2->sin6_port); |
| 162 } |
| 163 default: |
| 164 return PP_FALSE; |
126 } | 165 } |
127 | |
128 if (GetFamily(addr1) == AF_INET6) { | |
129 const sockaddr_in6* a1 = reinterpret_cast<const sockaddr_in6*>(addr1->data); | |
130 const sockaddr_in6* a2 = reinterpret_cast<const sockaddr_in6*>(addr2->data); | |
131 return PP_FromBool(a1->sin6_port == a2->sin6_port); | |
132 } | |
133 | |
134 return PP_FALSE; | |
135 } | 166 } |
136 | 167 |
137 #if defined(OS_WIN) || defined(OS_MACOSX) | 168 #if defined(OS_WIN) || defined(OS_MACOSX) |
138 std::string ConvertIPv4AddressToString(const sockaddr_in* a, | 169 std::string ConvertIPv4AddressToString(const sockaddr_in* a, |
139 bool include_port) { | 170 bool include_port) { |
140 unsigned ip = ntohl(a->sin_addr.s_addr); | 171 unsigned ip = ntohl(a->sin_addr.s_addr); |
141 unsigned port = ntohs(a->sin_port); | 172 unsigned port = ntohs(a->sin_port); |
142 std::string description = base::StringPrintf( | 173 std::string description = base::StringPrintf( |
143 "%u.%u.%u.%u", | 174 "%u.%u.%u.%u", |
144 (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); | 175 (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 PP_Bool include_port) { | 260 PP_Bool include_port) { |
230 if (!NetAddressPrivateImpl::ValidateNetAddress(*addr)) | 261 if (!NetAddressPrivateImpl::ValidateNetAddress(*addr)) |
231 return PP_MakeUndefined(); | 262 return PP_MakeUndefined(); |
232 | 263 |
233 #if defined(OS_WIN) || defined(OS_MACOSX) | 264 #if defined(OS_WIN) || defined(OS_MACOSX) |
234 // On Windows, |NetAddressToString()| doesn't work in the sandbox. On Mac, | 265 // On Windows, |NetAddressToString()| doesn't work in the sandbox. On Mac, |
235 // the output isn't consistent with RFC 5952, at least on Mac OS 10.6: | 266 // the output isn't consistent with RFC 5952, at least on Mac OS 10.6: |
236 // |getnameinfo()| collapses length-one runs of zeros (and also doesn't | 267 // |getnameinfo()| collapses length-one runs of zeros (and also doesn't |
237 // display the scope). | 268 // display the scope). |
238 // TODO(viettrungluu): Consider switching to this on Linux. | 269 // TODO(viettrungluu): Consider switching to this on Linux. |
239 switch (GetFamily(addr)) { | 270 switch (GetFamilyInternal(addr)) { |
240 case AF_INET: { | 271 case AF_INET: { |
241 const sockaddr_in* a = reinterpret_cast<const sockaddr_in*>(addr->data); | 272 const sockaddr_in* a = reinterpret_cast<const sockaddr_in*>(addr->data); |
242 return StringVar::StringToPPVar( | 273 return StringVar::StringToPPVar( |
243 ConvertIPv4AddressToString(a, !!include_port)); | 274 ConvertIPv4AddressToString(a, !!include_port)); |
244 } | 275 } |
245 case AF_INET6: { | 276 case AF_INET6: { |
246 const sockaddr_in6* a = reinterpret_cast<const sockaddr_in6*>(addr->data); | 277 const sockaddr_in6* a = reinterpret_cast<const sockaddr_in6*>(addr->data); |
247 return StringVar::StringToPPVar( | 278 return StringVar::StringToPPVar( |
248 ConvertIPv6AddressToString(a, !!include_port)); | 279 ConvertIPv6AddressToString(a, !!include_port)); |
249 } | 280 } |
(...skipping 11 matching lines...) Expand all Loading... |
261 return StringVar::StringToPPVar(description); | 292 return StringVar::StringToPPVar(description); |
262 #endif | 293 #endif |
263 } | 294 } |
264 | 295 |
265 PP_Bool ReplacePort(const struct PP_NetAddress_Private* src_addr, | 296 PP_Bool ReplacePort(const struct PP_NetAddress_Private* src_addr, |
266 uint16_t port, | 297 uint16_t port, |
267 struct PP_NetAddress_Private* dest_addr) { | 298 struct PP_NetAddress_Private* dest_addr) { |
268 if (!NetAddressPrivateImpl::ValidateNetAddress(*src_addr)) | 299 if (!NetAddressPrivateImpl::ValidateNetAddress(*src_addr)) |
269 return PP_FALSE; | 300 return PP_FALSE; |
270 | 301 |
271 if (GetFamily(src_addr) == AF_INET) { | 302 switch (GetFamilyInternal(src_addr)) { |
272 memmove(dest_addr, src_addr, sizeof(*src_addr)); | 303 case AF_INET: { |
273 reinterpret_cast<sockaddr_in*>(dest_addr->data)->sin_port = htons(port); | 304 memmove(dest_addr, src_addr, sizeof(*src_addr)); |
274 return PP_TRUE; | 305 reinterpret_cast<sockaddr_in*>(dest_addr->data)->sin_port = htons(port); |
| 306 return PP_TRUE; |
| 307 } |
| 308 case AF_INET6: { |
| 309 memmove(dest_addr, src_addr, sizeof(*src_addr)); |
| 310 reinterpret_cast<sockaddr_in6*>(dest_addr->data)->sin6_port = htons(port); |
| 311 return PP_TRUE; |
| 312 } |
| 313 default: |
| 314 return PP_FALSE; |
275 } | 315 } |
276 | |
277 if (GetFamily(src_addr) == AF_INET6) { | |
278 memmove(dest_addr, src_addr, sizeof(*src_addr)); | |
279 reinterpret_cast<sockaddr_in6*>(dest_addr->data)->sin6_port = htons(port); | |
280 return PP_TRUE; | |
281 } | |
282 | |
283 return PP_FALSE; | |
284 } | 316 } |
285 | 317 |
286 void GetAnyAddress(PP_Bool is_ipv6, PP_NetAddress_Private* addr) { | 318 void GetAnyAddress(PP_Bool is_ipv6, PP_NetAddress_Private* addr) { |
287 memset(addr->data, 0, arraysize(addr->data) * sizeof(addr->data[0])); | 319 memset(addr->data, 0, arraysize(addr->data) * sizeof(addr->data[0])); |
288 if (is_ipv6) { | 320 if (is_ipv6) { |
289 sockaddr_in6* a = reinterpret_cast<sockaddr_in6*>(addr->data); | 321 sockaddr_in6* a = reinterpret_cast<sockaddr_in6*>(addr->data); |
290 addr->size = sizeof(*a); | 322 addr->size = sizeof(*a); |
291 a->sin6_family = AF_INET6; | 323 a->sin6_family = AF_INET6; |
292 a->sin6_addr = in6addr_any; | 324 a->sin6_addr = in6addr_any; |
293 } else { | 325 } else { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 // static | 368 // static |
337 const PP_NetAddress_Private NetAddressPrivateImpl::kInvalidNetAddress = { 0 }; | 369 const PP_NetAddress_Private NetAddressPrivateImpl::kInvalidNetAddress = { 0 }; |
338 | 370 |
339 // static | 371 // static |
340 bool NetAddressPrivateImpl::ValidateNetAddress( | 372 bool NetAddressPrivateImpl::ValidateNetAddress( |
341 const PP_NetAddress_Private& addr) { | 373 const PP_NetAddress_Private& addr) { |
342 if (addr.size < sizeof(reinterpret_cast<sockaddr*>(0)->sa_family)) | 374 if (addr.size < sizeof(reinterpret_cast<sockaddr*>(0)->sa_family)) |
343 return false; | 375 return false; |
344 | 376 |
345 // TODO(viettrungluu): more careful validation? | 377 // TODO(viettrungluu): more careful validation? |
346 // Just do a size check for AF_INET. | 378 switch (GetFamilyInternal(&addr)) { |
347 if (GetFamily(&addr) == AF_INET && addr.size >= sizeof(sockaddr_in)) | 379 case AF_INET: |
348 return true; | 380 // Just do a size check for AF_INET. |
349 | 381 if (addr.size >= sizeof(sockaddr_in)) |
350 // Ditto for AF_INET6. | 382 return true; |
351 if (GetFamily(&addr) == AF_INET6 && addr.size >= sizeof(sockaddr_in6)) | 383 break; |
352 return true; | 384 case AF_INET6: |
| 385 // Ditto for AF_INET6. |
| 386 if (addr.size >= sizeof(sockaddr_in6)) |
| 387 return true; |
| 388 break; |
| 389 default: |
| 390 break; |
| 391 } |
353 | 392 |
354 // Reject everything else. | 393 // Reject everything else. |
355 return false; | 394 return false; |
356 } | 395 } |
357 | 396 |
358 // static | 397 // static |
359 bool NetAddressPrivateImpl::SockaddrToNetAddress( | 398 bool NetAddressPrivateImpl::SockaddrToNetAddress( |
360 const sockaddr* sa, | 399 const sockaddr* sa, |
361 uint32_t sa_length, | 400 uint32_t sa_length, |
362 PP_NetAddress_Private* net_addr) { | 401 PP_NetAddress_Private* net_addr) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 net::IPEndPoint ip_end_point; | 453 net::IPEndPoint ip_end_point; |
415 if (!NetAddressToIPEndPoint(net_addr, &ip_end_point)) | 454 if (!NetAddressToIPEndPoint(net_addr, &ip_end_point)) |
416 return false; | 455 return false; |
417 | 456 |
418 *address_list = net::AddressList::CreateFromIPAddress(ip_end_point.address(), | 457 *address_list = net::AddressList::CreateFromIPAddress(ip_end_point.address(), |
419 ip_end_point.port()); | 458 ip_end_point.port()); |
420 return true; | 459 return true; |
421 } | 460 } |
422 | 461 |
423 } // namespace ppapi | 462 } // namespace ppapi |
OLD | NEW |