Chromium Code Reviews| 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 |