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 11 matching lines...) Expand all Loading... | |
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|. | 31 // The type of |sockaddr::sa_family|. |
32 typedef ADDRESS_FAMILY sa_family_t; | 32 typedef ADDRESS_FAMILY sa_family_t; |
viettrungluu
2012/02/13 22:26:39
Probably this is no longer needed.
yzshen1
2012/02/13 22:38:41
I've fixed it before landing.
| |
33 | 33 |
34 #define s6_addr16 u.Word | 34 #define s6_addr16 u.Word |
35 #endif | 35 #endif |
36 | 36 |
37 // 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 |
38 // 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 |
39 // 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 |
40 // namespace so it magically gets hooked up in the proper places. | 40 // namespace so it magically gets hooked up in the proper places. |
41 | 41 |
42 namespace ppapi { | 42 namespace ppapi { |
43 | 43 |
44 namespace { | 44 namespace { |
45 | 45 |
46 // 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. |
47 #if !defined(OS_OPENBSD) | 47 #if !defined(OS_OPENBSD) |
48 // 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 |
49 // since the data is opaque elsewhere.) | 49 // since the data is opaque elsewhere.) |
50 COMPILE_ASSERT(sizeof(reinterpret_cast<PP_NetAddress_Private*>(0)->data) >= | 50 COMPILE_ASSERT(sizeof(reinterpret_cast<PP_NetAddress_Private*>(0)->data) >= |
51 sizeof(sockaddr_storage), PP_NetAddress_Private_data_too_small); | 51 sizeof(sockaddr_storage), PP_NetAddress_Private_data_too_small); |
52 #endif | 52 #endif |
53 | 53 |
54 inline sa_family_t GetFamily(const PP_NetAddress_Private& addr) { | 54 uint16_t GetFamily(const PP_NetAddress_Private* addr) { |
55 return reinterpret_cast<const sockaddr*>(addr.data)->sa_family; | 55 return reinterpret_cast<const sockaddr*>(addr->data)->sa_family; |
viettrungluu
2012/02/13 22:26:39
Probably this should have a cast to uint16_t (from
yzshen1
2012/02/13 22:38:41
This sounds good to me.
| |
56 } | 56 } |
57 | 57 |
58 uint16_t GetPort(const PP_NetAddress_Private* addr) { | |
59 if (GetFamily(addr) == AF_INET) { | |
60 const sockaddr_in* a = reinterpret_cast<const sockaddr_in*>(addr->data); | |
61 return ntohs(a->sin_port); | |
62 } else if (GetFamily(addr) == AF_INET6) { | |
63 const sockaddr_in6* a = reinterpret_cast<const sockaddr_in6*>(addr->data); | |
64 return ntohs(a->sin6_port); | |
65 } | |
66 | |
67 return 0; | |
68 } | |
69 | |
70 PP_Bool GetAddress(const struct PP_NetAddress_Private* addr, void* address, | |
71 uint16_t address_size) { | |
72 if (GetFamily(addr) == AF_INET) { | |
73 const sockaddr_in* a = reinterpret_cast<const sockaddr_in*>(addr->data); | |
74 if (address_size >= sizeof(a->sin_addr.s_addr)) { | |
75 memcpy(address, &(a->sin_addr.s_addr), sizeof(a->sin_addr.s_addr)); | |
76 return PP_TRUE; | |
77 } | |
78 } else if (GetFamily(addr) == AF_INET6) { | |
79 const sockaddr_in6* a = reinterpret_cast<const sockaddr_in6*>(addr->data); | |
80 if (address_size >= sizeof(a->sin6_addr.s6_addr)) { | |
81 memcpy(address, | |
82 &(a->sin6_addr.s6_addr), | |
83 sizeof(a->sin6_addr.s6_addr)); | |
84 return PP_TRUE; | |
85 } | |
86 } | |
87 | |
88 return PP_FALSE; | |
89 } | |
90 | |
viettrungluu
2012/02/13 22:26:39
Extra blank line.
yzshen1
2012/02/13 22:38:41
I've fixed it before landing.
| |
91 | |
58 PP_Bool AreHostsEqual(const PP_NetAddress_Private* addr1, | 92 PP_Bool AreHostsEqual(const PP_NetAddress_Private* addr1, |
59 const PP_NetAddress_Private* addr2) { | 93 const PP_NetAddress_Private* addr2) { |
60 if (!NetAddressPrivateImpl::ValidateNetAddress(*addr1) || | 94 if (!NetAddressPrivateImpl::ValidateNetAddress(*addr1) || |
61 !NetAddressPrivateImpl::ValidateNetAddress(*addr2)) | 95 !NetAddressPrivateImpl::ValidateNetAddress(*addr2)) |
62 return PP_FALSE; | 96 return PP_FALSE; |
63 | 97 |
64 if (GetFamily(*addr1) != GetFamily(*addr2)) | 98 if (GetFamily(addr1) != GetFamily(addr2)) |
65 return PP_FALSE; | 99 return PP_FALSE; |
66 | 100 |
67 if (GetFamily(*addr1) == AF_INET) { | 101 if (GetFamily(addr1) == AF_INET) { |
68 const sockaddr_in* a1 = reinterpret_cast<const sockaddr_in*>(addr1->data); | 102 const sockaddr_in* a1 = reinterpret_cast<const sockaddr_in*>(addr1->data); |
69 const sockaddr_in* a2 = reinterpret_cast<const sockaddr_in*>(addr2->data); | 103 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); | 104 return PP_FromBool(a1->sin_addr.s_addr == a2->sin_addr.s_addr); |
71 } | 105 } |
72 | 106 |
73 if (GetFamily(*addr1) == AF_INET6) { | 107 if (GetFamily(addr1) == AF_INET6) { |
74 const sockaddr_in6* a1 = reinterpret_cast<const sockaddr_in6*>(addr1->data); | 108 const sockaddr_in6* a1 = reinterpret_cast<const sockaddr_in6*>(addr1->data); |
75 const sockaddr_in6* a2 = reinterpret_cast<const sockaddr_in6*>(addr2->data); | 109 const sockaddr_in6* a2 = reinterpret_cast<const sockaddr_in6*>(addr2->data); |
76 return PP_FromBool(a1->sin6_flowinfo == a2->sin6_flowinfo && | 110 return PP_FromBool(a1->sin6_flowinfo == a2->sin6_flowinfo && |
77 memcmp(&a1->sin6_addr, &a2->sin6_addr, | 111 memcmp(&a1->sin6_addr, &a2->sin6_addr, |
78 sizeof(a1->sin6_addr)) == 0 && | 112 sizeof(a1->sin6_addr)) == 0 && |
79 a1->sin6_scope_id == a2->sin6_scope_id); | 113 a1->sin6_scope_id == a2->sin6_scope_id); |
80 } | 114 } |
81 | 115 |
82 return PP_FALSE; | 116 return PP_FALSE; |
83 } | 117 } |
84 | 118 |
85 PP_Bool AreEqual(const PP_NetAddress_Private* addr1, | 119 PP_Bool AreEqual(const PP_NetAddress_Private* addr1, |
86 const PP_NetAddress_Private* addr2) { | 120 const PP_NetAddress_Private* addr2) { |
87 // |AreHostsEqual()| will also validate the addresses and return false if | 121 // |AreHostsEqual()| will also validate the addresses and return false if |
88 // either is invalid. | 122 // either is invalid. |
89 if (!AreHostsEqual(addr1, addr2)) | 123 if (!AreHostsEqual(addr1, addr2)) |
90 return PP_FALSE; | 124 return PP_FALSE; |
91 | 125 |
92 // Note: Here, we know that |addr1| and |addr2| have the same family. | 126 // Note: Here, we know that |addr1| and |addr2| have the same family. |
93 if (GetFamily(*addr1) == AF_INET) { | 127 if (GetFamily(addr1) == AF_INET) { |
94 const sockaddr_in* a1 = reinterpret_cast<const sockaddr_in*>(addr1->data); | 128 const sockaddr_in* a1 = reinterpret_cast<const sockaddr_in*>(addr1->data); |
95 const sockaddr_in* a2 = reinterpret_cast<const sockaddr_in*>(addr2->data); | 129 const sockaddr_in* a2 = reinterpret_cast<const sockaddr_in*>(addr2->data); |
96 return PP_FromBool(a1->sin_port == a2->sin_port); | 130 return PP_FromBool(a1->sin_port == a2->sin_port); |
97 } | 131 } |
98 | 132 |
99 if (GetFamily(*addr1) == AF_INET6) { | 133 if (GetFamily(addr1) == AF_INET6) { |
100 const sockaddr_in6* a1 = reinterpret_cast<const sockaddr_in6*>(addr1->data); | 134 const sockaddr_in6* a1 = reinterpret_cast<const sockaddr_in6*>(addr1->data); |
101 const sockaddr_in6* a2 = reinterpret_cast<const sockaddr_in6*>(addr2->data); | 135 const sockaddr_in6* a2 = reinterpret_cast<const sockaddr_in6*>(addr2->data); |
102 return PP_FromBool(a1->sin6_port == a2->sin6_port); | 136 return PP_FromBool(a1->sin6_port == a2->sin6_port); |
103 } | 137 } |
104 | 138 |
105 return PP_FALSE; | 139 return PP_FALSE; |
106 } | 140 } |
107 | 141 |
108 #if defined(OS_WIN) || defined(OS_MACOSX) | 142 #if defined(OS_WIN) || defined(OS_MACOSX) |
109 std::string ConvertIPv4AddressToString(const sockaddr_in* a, | 143 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) { | 234 PP_Bool include_port) { |
201 if (!NetAddressPrivateImpl::ValidateNetAddress(*addr)) | 235 if (!NetAddressPrivateImpl::ValidateNetAddress(*addr)) |
202 return PP_MakeUndefined(); | 236 return PP_MakeUndefined(); |
203 | 237 |
204 #if defined(OS_WIN) || defined(OS_MACOSX) | 238 #if defined(OS_WIN) || defined(OS_MACOSX) |
205 // On Windows, |NetAddressToString()| doesn't work in the sandbox. On Mac, | 239 // 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: | 240 // 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 | 241 // |getnameinfo()| collapses length-one runs of zeros (and also doesn't |
208 // display the scope). | 242 // display the scope). |
209 // TODO(viettrungluu): Consider switching to this on Linux. | 243 // TODO(viettrungluu): Consider switching to this on Linux. |
210 switch (GetFamily(*addr)) { | 244 switch (GetFamily(addr)) { |
211 case AF_INET: { | 245 case AF_INET: { |
212 const sockaddr_in* a = reinterpret_cast<const sockaddr_in*>(addr->data); | 246 const sockaddr_in* a = reinterpret_cast<const sockaddr_in*>(addr->data); |
213 return StringVar::StringToPPVar( | 247 return StringVar::StringToPPVar( |
214 ConvertIPv4AddressToString(a, !!include_port)); | 248 ConvertIPv4AddressToString(a, !!include_port)); |
215 } | 249 } |
216 case AF_INET6: { | 250 case AF_INET6: { |
217 const sockaddr_in6* a = reinterpret_cast<const sockaddr_in6*>(addr->data); | 251 const sockaddr_in6* a = reinterpret_cast<const sockaddr_in6*>(addr->data); |
218 return StringVar::StringToPPVar( | 252 return StringVar::StringToPPVar( |
219 ConvertIPv6AddressToString(a, !!include_port)); | 253 ConvertIPv6AddressToString(a, !!include_port)); |
220 } | 254 } |
(...skipping 11 matching lines...) Expand all Loading... | |
232 return StringVar::StringToPPVar(description); | 266 return StringVar::StringToPPVar(description); |
233 #endif | 267 #endif |
234 } | 268 } |
235 | 269 |
236 PP_Bool ReplacePort(const struct PP_NetAddress_Private* src_addr, | 270 PP_Bool ReplacePort(const struct PP_NetAddress_Private* src_addr, |
237 uint16_t port, | 271 uint16_t port, |
238 struct PP_NetAddress_Private* dest_addr) { | 272 struct PP_NetAddress_Private* dest_addr) { |
239 if (!NetAddressPrivateImpl::ValidateNetAddress(*src_addr)) | 273 if (!NetAddressPrivateImpl::ValidateNetAddress(*src_addr)) |
240 return PP_FALSE; | 274 return PP_FALSE; |
241 | 275 |
242 if (GetFamily(*src_addr) == AF_INET) { | 276 if (GetFamily(src_addr) == AF_INET) { |
243 memmove(dest_addr, src_addr, sizeof(*src_addr)); | 277 memmove(dest_addr, src_addr, sizeof(*src_addr)); |
244 reinterpret_cast<sockaddr_in*>(dest_addr->data)->sin_port = htons(port); | 278 reinterpret_cast<sockaddr_in*>(dest_addr->data)->sin_port = htons(port); |
245 return PP_TRUE; | 279 return PP_TRUE; |
246 } | 280 } |
247 | 281 |
248 if (GetFamily(*src_addr) == AF_INET6) { | 282 if (GetFamily(src_addr) == AF_INET6) { |
249 memmove(dest_addr, src_addr, sizeof(*src_addr)); | 283 memmove(dest_addr, src_addr, sizeof(*src_addr)); |
250 reinterpret_cast<sockaddr_in6*>(dest_addr->data)->sin6_port = htons(port); | 284 reinterpret_cast<sockaddr_in6*>(dest_addr->data)->sin6_port = htons(port); |
251 return PP_TRUE; | 285 return PP_TRUE; |
252 } | 286 } |
253 | 287 |
254 return PP_FALSE; | 288 return PP_FALSE; |
255 } | 289 } |
256 | 290 |
257 void GetAnyAddress(PP_Bool is_ipv6, PP_NetAddress_Private* addr) { | 291 void GetAnyAddress(PP_Bool is_ipv6, PP_NetAddress_Private* addr) { |
258 memset(addr->data, 0, arraysize(addr->data) * sizeof(addr->data[0])); | 292 memset(addr->data, 0, arraysize(addr->data) * sizeof(addr->data[0])); |
259 if (is_ipv6) { | 293 if (is_ipv6) { |
260 sockaddr_in6* a = reinterpret_cast<sockaddr_in6*>(addr->data); | 294 sockaddr_in6* a = reinterpret_cast<sockaddr_in6*>(addr->data); |
261 addr->size = sizeof(*a); | 295 addr->size = sizeof(*a); |
262 a->sin6_family = AF_INET6; | 296 a->sin6_family = AF_INET6; |
263 a->sin6_addr = in6addr_any; | 297 a->sin6_addr = in6addr_any; |
264 } else { | 298 } else { |
265 sockaddr_in* a = reinterpret_cast<sockaddr_in*>(addr->data); | 299 sockaddr_in* a = reinterpret_cast<sockaddr_in*>(addr->data); |
266 addr->size = sizeof(*a); | 300 addr->size = sizeof(*a); |
267 a->sin_family = AF_INET; | 301 a->sin_family = AF_INET; |
268 a->sin_addr.s_addr = INADDR_ANY; | 302 a->sin_addr.s_addr = INADDR_ANY; |
269 } | 303 } |
270 } | 304 } |
271 | 305 |
272 const PPB_NetAddress_Private net_address_private_interface = { | 306 const PPB_NetAddress_Private_0_1 net_address_private_interface_0_1 = { |
273 &AreEqual, | 307 &AreEqual, |
274 &AreHostsEqual, | 308 &AreHostsEqual, |
275 &Describe, | 309 &Describe, |
276 &ReplacePort, | 310 &ReplacePort, |
277 &GetAnyAddress | 311 &GetAnyAddress |
278 }; | 312 }; |
279 | 313 |
314 const PPB_NetAddress_Private net_address_private_interface_1_0 = { | |
315 &AreEqual, | |
316 &AreHostsEqual, | |
317 &Describe, | |
318 &ReplacePort, | |
319 &GetAnyAddress, | |
320 &GetFamily, | |
321 &GetPort, | |
322 &GetAddress | |
323 }; | |
324 | |
280 } // namespace | 325 } // namespace |
281 | 326 |
282 namespace thunk { | 327 namespace thunk { |
283 | 328 |
284 PPAPI_THUNK_EXPORT const PPB_NetAddress_Private_0_1* | 329 PPAPI_THUNK_EXPORT const PPB_NetAddress_Private_0_1* |
285 GetPPB_NetAddress_Private_0_1_Thunk() { | 330 GetPPB_NetAddress_Private_0_1_Thunk() { |
286 return &net_address_private_interface; | 331 return &net_address_private_interface_0_1; |
332 } | |
333 | |
334 PPAPI_THUNK_EXPORT const PPB_NetAddress_Private_1_0* | |
335 GetPPB_NetAddress_Private_1_0_Thunk() { | |
336 return &net_address_private_interface_1_0; | |
287 } | 337 } |
288 | 338 |
289 } // namespace thunk | 339 } // namespace thunk |
290 | 340 |
291 // static | 341 // static |
292 const PP_NetAddress_Private NetAddressPrivateImpl::kInvalidNetAddress = { 0 }; | 342 const PP_NetAddress_Private NetAddressPrivateImpl::kInvalidNetAddress = { 0 }; |
293 | 343 |
294 // static | 344 // static |
295 bool NetAddressPrivateImpl::ValidateNetAddress( | 345 bool NetAddressPrivateImpl::ValidateNetAddress( |
296 const PP_NetAddress_Private& addr) { | 346 const PP_NetAddress_Private& addr) { |
297 if (addr.size < sizeof(reinterpret_cast<sockaddr*>(0)->sa_family)) | 347 if (addr.size < sizeof(reinterpret_cast<sockaddr*>(0)->sa_family)) |
298 return false; | 348 return false; |
299 | 349 |
300 // TODO(viettrungluu): more careful validation? | 350 // TODO(viettrungluu): more careful validation? |
301 // Just do a size check for AF_INET. | 351 // Just do a size check for AF_INET. |
302 if (GetFamily(addr) == AF_INET && addr.size >= sizeof(sockaddr_in)) | 352 if (GetFamily(&addr) == AF_INET && addr.size >= sizeof(sockaddr_in)) |
viettrungluu
2012/02/13 22:26:39
It's not necessarily the case that AF_INET is a ui
| |
303 return true; | 353 return true; |
304 | 354 |
305 // Ditto for AF_INET6. | 355 // Ditto for AF_INET6. |
306 if (GetFamily(addr) == AF_INET6 && addr.size >= sizeof(sockaddr_in6)) | 356 if (GetFamily(&addr) == AF_INET6 && addr.size >= sizeof(sockaddr_in6)) |
307 return true; | 357 return true; |
308 | 358 |
309 // Reject everything else. | 359 // Reject everything else. |
310 return false; | 360 return false; |
311 } | 361 } |
312 | 362 |
313 // static | 363 // static |
314 bool NetAddressPrivateImpl::SockaddrToNetAddress( | 364 bool NetAddressPrivateImpl::SockaddrToNetAddress( |
315 const sockaddr* sa, | 365 const sockaddr* sa, |
316 uint32_t sa_length, | 366 uint32_t sa_length, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
369 net::IPEndPoint ip_end_point; | 419 net::IPEndPoint ip_end_point; |
370 if (!NetAddressToIPEndPoint(net_addr, &ip_end_point)) | 420 if (!NetAddressToIPEndPoint(net_addr, &ip_end_point)) |
371 return false; | 421 return false; |
372 | 422 |
373 *address_list = net::AddressList::CreateFromIPAddress(ip_end_point.address(), | 423 *address_list = net::AddressList::CreateFromIPAddress(ip_end_point.address(), |
374 ip_end_point.port()); | 424 ip_end_point.port()); |
375 return true; | 425 return true; |
376 } | 426 } |
377 | 427 |
378 } // namespace ppapi | 428 } // namespace ppapi |
OLD | NEW |