| 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 |