OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 #ifndef __STDC_LIMIT_MACROS | 5 #ifndef __STDC_LIMIT_MACROS |
6 #define __STDC_LIMIT_MACROS | 6 #define __STDC_LIMIT_MACROS |
7 #endif | 7 #endif |
8 | 8 |
9 #include "nacl_io/host_resolver.h" | 9 #include "nacl_io/host_resolver.h" |
10 | 10 |
11 #include <assert.h> | 11 #include <assert.h> |
12 #include <stdint.h> | 12 #include <stdint.h> |
13 #include <stdlib.h> | 13 #include <stdlib.h> |
14 #include <string.h> | 14 #include <string.h> |
15 | 15 |
16 #include "nacl_io/kernel_proxy.h" | 16 #include "nacl_io/kernel_proxy.h" |
| 17 #include "nacl_io/log.h" |
17 #include "nacl_io/ossocket.h" | 18 #include "nacl_io/ossocket.h" |
18 #include "nacl_io/pepper_interface.h" | 19 #include "nacl_io/pepper_interface.h" |
19 | 20 |
20 #ifdef PROVIDES_SOCKET_API | 21 #ifdef PROVIDES_SOCKET_API |
21 | 22 |
22 namespace { | 23 namespace { |
23 | 24 |
24 void HintsToPPHints(const addrinfo* hints, PP_HostResolver_Hint* pp_hints) { | 25 void HintsToPPHints(const addrinfo* hints, PP_HostResolver_Hint* pp_hints) { |
25 memset(pp_hints, 0, sizeof(*pp_hints)); | 26 memset(pp_hints, 0, sizeof(*pp_hints)); |
26 | 27 |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 } | 221 } |
221 } | 222 } |
222 | 223 |
223 int HostResolver::getaddrinfo(const char* node, | 224 int HostResolver::getaddrinfo(const char* node, |
224 const char* service, | 225 const char* service, |
225 const struct addrinfo* hints_in, | 226 const struct addrinfo* hints_in, |
226 struct addrinfo** result) { | 227 struct addrinfo** result) { |
227 *result = NULL; | 228 *result = NULL; |
228 struct addrinfo* end = NULL; | 229 struct addrinfo* end = NULL; |
229 | 230 |
230 if (node == NULL && service == NULL) | 231 if (node == NULL && service == NULL) { |
| 232 LOG_TRACE("node and service are NULL."); |
231 return EAI_NONAME; | 233 return EAI_NONAME; |
| 234 } |
232 | 235 |
233 // Check the service name (port). Currently we only handle numeric | 236 // Check the service name (port). Currently we only handle numeric |
234 // services. | 237 // services. |
235 long port = 0; | 238 long port = 0; |
236 if (service != NULL) { | 239 if (service != NULL) { |
237 char* cp; | 240 char* cp; |
238 port = strtol(service, &cp, 10); | 241 port = strtol(service, &cp, 10); |
239 if (port >= 0 && port <= UINT16_MAX && *cp == '\0') { | 242 if (port >= 0 && port <= UINT16_MAX && *cp == '\0') { |
240 port = htons(port); | 243 port = htons(port); |
241 } else { | 244 } else { |
| 245 LOG_TRACE("Service \"%s\" not supported.", service); |
242 return EAI_SERVICE; | 246 return EAI_SERVICE; |
243 } | 247 } |
244 } | 248 } |
245 | 249 |
246 struct addrinfo default_hints; | 250 struct addrinfo default_hints; |
247 memset(&default_hints, 0, sizeof(default_hints)); | 251 memset(&default_hints, 0, sizeof(default_hints)); |
248 const struct addrinfo* hints = hints_in ? hints_in : &default_hints; | 252 const struct addrinfo* hints = hints_in ? hints_in : &default_hints; |
249 | 253 |
250 // Verify values passed in hints structure | 254 // Verify values passed in hints structure |
251 switch (hints->ai_family) { | 255 switch (hints->ai_family) { |
252 case AF_INET6: | 256 case AF_INET6: |
253 case AF_INET: | 257 case AF_INET: |
254 case AF_UNSPEC: | 258 case AF_UNSPEC: |
255 break; | 259 break; |
256 default: | 260 default: |
| 261 LOG_TRACE("Unknown family: %d.", hints->ai_family); |
257 return EAI_FAMILY; | 262 return EAI_FAMILY; |
258 } | 263 } |
259 | 264 |
260 struct sockaddr_in addr_in; | 265 struct sockaddr_in addr_in; |
261 memset(&addr_in, 0, sizeof(addr_in)); | 266 memset(&addr_in, 0, sizeof(addr_in)); |
262 addr_in.sin_family = AF_INET; | 267 addr_in.sin_family = AF_INET; |
263 addr_in.sin_port = port; | 268 addr_in.sin_port = port; |
264 | 269 |
265 struct sockaddr_in6 addr_in6; | 270 struct sockaddr_in6 addr_in6; |
266 memset(&addr_in6, 0, sizeof(addr_in6)); | 271 memset(&addr_in6, 0, sizeof(addr_in6)); |
(...skipping 29 matching lines...) Expand all Loading... |
296 CreateAddrInfo(hints, (sockaddr*)&addr_in6, NULL, result, &end); | 301 CreateAddrInfo(hints, (sockaddr*)&addr_in6, NULL, result, &end); |
297 } | 302 } |
298 | 303 |
299 if (hints->ai_family == AF_INET || hints->ai_family == AF_UNSPEC) { | 304 if (hints->ai_family == AF_INET || hints->ai_family == AF_UNSPEC) { |
300 addr_in.sin_addr.s_addr = INADDR_ANY; | 305 addr_in.sin_addr.s_addr = INADDR_ANY; |
301 CreateAddrInfo(hints, (sockaddr*)&addr_in, NULL, result, &end); | 306 CreateAddrInfo(hints, (sockaddr*)&addr_in, NULL, result, &end); |
302 } | 307 } |
303 return 0; | 308 return 0; |
304 } | 309 } |
305 | 310 |
306 if (NULL == ppapi_) | 311 if (NULL == ppapi_) { |
| 312 LOG_ERROR("ppapi_ is NULL."); |
307 return EAI_SYSTEM; | 313 return EAI_SYSTEM; |
| 314 } |
308 | 315 |
309 // Use PPAPI interface to resolve nodename | 316 // Use PPAPI interface to resolve nodename |
310 HostResolverInterface* resolver_iface = ppapi_->GetHostResolverInterface(); | 317 HostResolverInterface* resolver_iface = ppapi_->GetHostResolverInterface(); |
311 VarInterface* var_interface = ppapi_->GetVarInterface(); | 318 VarInterface* var_iface = ppapi_->GetVarInterface(); |
312 NetAddressInterface* netaddr_iface = ppapi_->GetNetAddressInterface(); | 319 NetAddressInterface* netaddr_iface = ppapi_->GetNetAddressInterface(); |
313 | 320 |
314 if (NULL == resolver_iface || NULL == var_interface || NULL == netaddr_iface) | 321 if (!(resolver_iface && var_iface && netaddr_iface)) { |
| 322 LOG_ERROR("Got NULL interface(s): %s%s%s", |
| 323 resolver_iface ? "" : "HostResolver ", |
| 324 var_iface ? "" : "Var ", |
| 325 netaddr_iface ? "" : "NetAddress"); |
315 return EAI_SYSTEM; | 326 return EAI_SYSTEM; |
| 327 } |
316 | 328 |
317 ScopedResource scoped_resolver(ppapi_, | 329 ScopedResource scoped_resolver(ppapi_, |
318 resolver_iface->Create(ppapi_->GetInstance())); | 330 resolver_iface->Create(ppapi_->GetInstance())); |
319 PP_Resource resolver = scoped_resolver.pp_resource(); | 331 PP_Resource resolver = scoped_resolver.pp_resource(); |
320 | 332 |
321 struct PP_HostResolver_Hint pp_hints; | 333 struct PP_HostResolver_Hint pp_hints; |
322 HintsToPPHints(hints, &pp_hints); | 334 HintsToPPHints(hints, &pp_hints); |
323 | 335 |
324 int err = resolver_iface->Resolve(resolver, | 336 int err = resolver_iface->Resolve(resolver, |
325 node, | 337 node, |
326 0, | 338 0, |
327 &pp_hints, | 339 &pp_hints, |
328 PP_BlockUntilComplete()); | 340 PP_BlockUntilComplete()); |
329 if (err) { | 341 if (err) { |
330 switch (err) { | 342 switch (err) { |
331 case PP_ERROR_NOACCESS: | 343 case PP_ERROR_NOACCESS: |
332 return EAI_SYSTEM; | 344 return EAI_SYSTEM; |
333 case PP_ERROR_NAME_NOT_RESOLVED: | 345 case PP_ERROR_NAME_NOT_RESOLVED: |
334 return EAI_NONAME; | 346 return EAI_NONAME; |
335 default: | 347 default: |
336 return EAI_SYSTEM; | 348 return EAI_SYSTEM; |
337 } | 349 } |
338 } | 350 } |
339 | 351 |
340 char* canon_name = NULL; | 352 char* canon_name = NULL; |
341 if (hints->ai_flags & AI_CANONNAME) { | 353 if (hints->ai_flags & AI_CANONNAME) { |
342 PP_Var name_var = resolver_iface->GetCanonicalName(resolver); | 354 PP_Var name_var = resolver_iface->GetCanonicalName(resolver); |
343 if (PP_VARTYPE_STRING == name_var.type) { | 355 if (PP_VARTYPE_STRING == name_var.type) { |
344 uint32_t len = 0; | 356 uint32_t len = 0; |
345 const char* tmp = var_interface->VarToUtf8(name_var, &len); | 357 const char* tmp = var_iface->VarToUtf8(name_var, &len); |
346 // For some reason GetCanonicalName alway returns an empty | 358 // For some reason GetCanonicalName alway returns an empty |
347 // string so this condition is never true. | 359 // string so this condition is never true. |
348 // TODO(sbc): investigate this issue with PPAPI team. | 360 // TODO(sbc): investigate this issue with PPAPI team. |
349 if (len > 0) { | 361 if (len > 0) { |
350 // Copy and NULL-terminate the UTF8 string var. | 362 // Copy and NULL-terminate the UTF8 string var. |
351 canon_name = static_cast<char*>(malloc(len + 1)); | 363 canon_name = static_cast<char*>(malloc(len + 1)); |
352 strncpy(canon_name, tmp, len); | 364 strncpy(canon_name, tmp, len); |
353 canon_name[len] = '\0'; | 365 canon_name[len] = '\0'; |
354 } | 366 } |
355 } | 367 } |
356 if (!canon_name) | 368 if (!canon_name) |
357 canon_name = strdup(node); | 369 canon_name = strdup(node); |
358 var_interface->Release(name_var); | 370 var_iface->Release(name_var); |
359 } | 371 } |
360 | 372 |
361 int num_addresses = resolver_iface->GetNetAddressCount(resolver); | 373 int num_addresses = resolver_iface->GetNetAddressCount(resolver); |
362 if (0 == num_addresses) | 374 if (0 == num_addresses) |
363 return EAI_NODATA; | 375 return EAI_NODATA; |
364 | 376 |
365 // Convert address to sockaddr struct. | 377 // Convert address to sockaddr struct. |
366 for (int i = 0; i < num_addresses; i++) { | 378 for (int i = 0; i < num_addresses; i++) { |
367 ScopedResource addr(ppapi_, resolver_iface->GetNetAddress(resolver, i)); | 379 ScopedResource addr(ppapi_, resolver_iface->GetNetAddress(resolver, i)); |
368 PP_Resource resource = addr.pp_resource(); | 380 PP_Resource resource = addr.pp_resource(); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 hostent_.h_addr_list = NULL; | 441 hostent_.h_addr_list = NULL; |
430 #if !defined(h_addr) | 442 #if !defined(h_addr) |
431 // Initialize h_addr separately in the case where it is not a macro. | 443 // Initialize h_addr separately in the case where it is not a macro. |
432 hostent_.h_addr = NULL; | 444 hostent_.h_addr = NULL; |
433 #endif | 445 #endif |
434 } | 446 } |
435 | 447 |
436 } // namespace nacl_io | 448 } // namespace nacl_io |
437 | 449 |
438 #endif // PROVIDES_SOCKET_API | 450 #endif // PROVIDES_SOCKET_API |
OLD | NEW |