|
60 | 60 | #if HAVE_LINUX_CAN_H
|
61 | 61 | #include <linux/can.h>
|
62 | 62 | #endif
|
| 63 | +#if HAVE_GETADDRINFO_A |
| 64 | +#include <signal.h> |
| 65 | +#include <stdatomic.h> |
| 66 | +#endif |
63 | 67 | #if HAVE_SYS_FILIO_H
|
64 | 68 | #include <sys/filio.h>
|
65 | 69 | #endif
|
@@ -335,37 +339,14 @@ static int32_t CopySockAddrToIPAddress(sockaddr* addr, sa_family_t family, IPAdd
|
335 | 339 | return -1;
|
336 | 340 | }
|
337 | 341 |
|
338 |
| -int32_t SystemNative_GetHostEntryForName(const uint8_t* address, int32_t addressFamily, HostEntry* entry) |
| 342 | +static int32_t GetHostEntries(const uint8_t* address, struct addrinfo* info, HostEntry* entry) |
339 | 343 | {
|
340 |
| - if (address == NULL || entry == NULL) |
341 |
| - { |
342 |
| - return GetAddrInfoErrorFlags_EAI_BADARG; |
343 |
| - } |
344 |
| - |
345 | 344 | int32_t ret = GetAddrInfoErrorFlags_EAI_SUCCESS;
|
346 | 345 |
|
347 |
| - struct addrinfo* info = NULL; |
348 | 346 | #if HAVE_GETIFADDRS
|
349 | 347 | struct ifaddrs* addrs = NULL;
|
350 | 348 | #endif
|
351 | 349 |
|
352 |
| - sa_family_t platformFamily; |
353 |
| - if (!TryConvertAddressFamilyPalToPlatform(addressFamily, &platformFamily)) |
354 |
| - { |
355 |
| - return GetAddrInfoErrorFlags_EAI_FAMILY; |
356 |
| - } |
357 |
| - |
358 |
| - struct addrinfo hint; |
359 |
| - memset(&hint, 0, sizeof(struct addrinfo)); |
360 |
| - hint.ai_flags = AI_CANONNAME; |
361 |
| - hint.ai_family = platformFamily; |
362 |
| - |
363 |
| - int result = getaddrinfo((const char*)address, NULL, &hint, &info); |
364 |
| - if (result != 0) |
365 |
| - { |
366 |
| - return ConvertGetAddrInfoAndGetNameInfoErrorsToPal(result); |
367 |
| - } |
368 |
| - |
369 | 350 | entry->CanonicalName = NULL;
|
370 | 351 | entry->Aliases = NULL;
|
371 | 352 | entry->IPAddressList = NULL;
|
@@ -393,7 +374,8 @@ int32_t SystemNative_GetHostEntryForName(const uint8_t* address, int32_t address
|
393 | 374 |
|
394 | 375 | #if HAVE_GETIFADDRS
|
395 | 376 | char name[_POSIX_HOST_NAME_MAX];
|
396 |
| - result = gethostname((char*)name, _POSIX_HOST_NAME_MAX); |
| 377 | + |
| 378 | + int result = gethostname((char*)name, _POSIX_HOST_NAME_MAX); |
397 | 379 |
|
398 | 380 | bool includeIPv4Loopback = true;
|
399 | 381 | bool includeIPv6Loopback = true;
|
@@ -443,6 +425,8 @@ int32_t SystemNative_GetHostEntryForName(const uint8_t* address, int32_t address
|
443 | 425 | }
|
444 | 426 | }
|
445 | 427 | }
|
| 428 | +#else |
| 429 | + (void)address; |
446 | 430 | #endif
|
447 | 431 |
|
448 | 432 | if (entry->IPAddressCount > 0)
|
@@ -519,6 +503,166 @@ int32_t SystemNative_GetHostEntryForName(const uint8_t* address, int32_t address
|
519 | 503 | return ret;
|
520 | 504 | }
|
521 | 505 |
|
| 506 | +#if HAVE_GETADDRINFO_A |
| 507 | +struct GetAddrInfoAsyncState |
| 508 | +{ |
| 509 | + struct gaicb gai_request; |
| 510 | + struct gaicb* gai_requests; |
| 511 | + struct sigevent sigevent; |
| 512 | + |
| 513 | + struct addrinfo hint; |
| 514 | + HostEntry* entry; |
| 515 | + GetHostEntryForNameCallback callback; |
| 516 | + char address[]; |
| 517 | +}; |
| 518 | + |
| 519 | +static void GetHostEntryForNameAsyncComplete(sigval_t context) |
| 520 | +{ |
| 521 | + struct GetAddrInfoAsyncState* state = (struct GetAddrInfoAsyncState*)context.sival_ptr; |
| 522 | + |
| 523 | + atomic_thread_fence(memory_order_acquire); |
| 524 | + |
| 525 | + GetHostEntryForNameCallback callback = state->callback; |
| 526 | + |
| 527 | + int ret = ConvertGetAddrInfoAndGetNameInfoErrorsToPal(gai_error(&state->gai_request)); |
| 528 | + |
| 529 | + if (ret == 0) |
| 530 | + { |
| 531 | + const uint8_t* address = (const uint8_t*)state->address; |
| 532 | + struct addrinfo* info = state->gai_request.ar_result; |
| 533 | + |
| 534 | + ret = GetHostEntries(address, info, state->entry); |
| 535 | + } |
| 536 | + |
| 537 | + assert(callback != NULL); |
| 538 | + callback(state->entry, ret); |
| 539 | + |
| 540 | + free(state); |
| 541 | +} |
| 542 | +#endif |
| 543 | + |
| 544 | +static bool TrySetAddressFamily(int32_t addressFamily, struct addrinfo* hint) |
| 545 | +{ |
| 546 | + sa_family_t platformFamily; |
| 547 | + if (!TryConvertAddressFamilyPalToPlatform(addressFamily, &platformFamily)) |
| 548 | + { |
| 549 | + return false; |
| 550 | + } |
| 551 | + |
| 552 | + memset(hint, 0, sizeof(struct addrinfo)); |
| 553 | + |
| 554 | + hint->ai_flags = AI_CANONNAME; |
| 555 | + hint->ai_family = platformFamily; |
| 556 | + |
| 557 | + return true; |
| 558 | +} |
| 559 | + |
| 560 | +int32_t SystemNative_PlatformSupportsGetAddrInfoAsync() |
| 561 | +{ |
| 562 | + return HAVE_GETADDRINFO_A; |
| 563 | +} |
| 564 | + |
| 565 | +int32_t SystemNative_GetHostEntryForName(const uint8_t* address, int32_t addressFamily, HostEntry* entry) |
| 566 | +{ |
| 567 | + if (address == NULL || entry == NULL) |
| 568 | + { |
| 569 | + return GetAddrInfoErrorFlags_EAI_BADARG; |
| 570 | + } |
| 571 | + |
| 572 | + struct addrinfo hint; |
| 573 | + if (!TrySetAddressFamily(addressFamily, &hint)) |
| 574 | + { |
| 575 | + return GetAddrInfoErrorFlags_EAI_FAMILY; |
| 576 | + } |
| 577 | + |
| 578 | + struct addrinfo* info = NULL; |
| 579 | + |
| 580 | + int result = getaddrinfo((const char*)address, NULL, &hint, &info); |
| 581 | + if (result != 0) |
| 582 | + { |
| 583 | + return ConvertGetAddrInfoAndGetNameInfoErrorsToPal(result); |
| 584 | + } |
| 585 | + |
| 586 | + return GetHostEntries(address, info, entry); |
| 587 | +} |
| 588 | + |
| 589 | +int32_t SystemNative_GetHostEntryForNameAsync(const uint8_t* address, int32_t addressFamily, HostEntry* entry, GetHostEntryForNameCallback callback) |
| 590 | +{ |
| 591 | +#if HAVE_GETADDRINFO_A |
| 592 | + if (address == NULL || entry == NULL) |
| 593 | + { |
| 594 | + return GetAddrInfoErrorFlags_EAI_BADARG; |
| 595 | + } |
| 596 | + |
| 597 | + size_t addrlen = strlen((const char*)address); |
| 598 | + |
| 599 | + if (addrlen > _POSIX_HOST_NAME_MAX) |
| 600 | + { |
| 601 | + return GetAddrInfoErrorFlags_EAI_BADARG; |
| 602 | + } |
| 603 | + |
| 604 | + sa_family_t platformFamily; |
| 605 | + if (!TryConvertAddressFamilyPalToPlatform(addressFamily, &platformFamily)) |
| 606 | + { |
| 607 | + return GetAddrInfoErrorFlags_EAI_FAMILY; |
| 608 | + } |
| 609 | + |
| 610 | + struct GetAddrInfoAsyncState* state = malloc(sizeof(*state) + addrlen + 1); |
| 611 | + |
| 612 | + if (state == NULL) |
| 613 | + { |
| 614 | + return GetAddrInfoErrorFlags_EAI_MEMORY; |
| 615 | + } |
| 616 | + |
| 617 | + if (!TrySetAddressFamily(addressFamily, &state->hint)) |
| 618 | + { |
| 619 | + free(state); |
| 620 | + return GetAddrInfoErrorFlags_EAI_FAMILY; |
| 621 | + } |
| 622 | + |
| 623 | + memcpy(state->address, address, addrlen + 1); |
| 624 | + |
| 625 | + *state = (struct GetAddrInfoAsyncState) { |
| 626 | + .gai_request = { |
| 627 | + .ar_name = state->address, |
| 628 | + .ar_service = NULL, |
| 629 | + .ar_request = &state->hint, |
| 630 | + .ar_result = NULL |
| 631 | + }, |
| 632 | + .gai_requests = &state->gai_request, |
| 633 | + .sigevent = { |
| 634 | + .sigev_notify = SIGEV_THREAD, |
| 635 | + .sigev_value = { |
| 636 | + .sival_ptr = state |
| 637 | + }, |
| 638 | + .sigev_notify_function = GetHostEntryForNameAsyncComplete |
| 639 | + }, |
| 640 | + .entry = entry, |
| 641 | + .callback = callback |
| 642 | + }; |
| 643 | + |
| 644 | + atomic_thread_fence(memory_order_release); |
| 645 | + |
| 646 | + int32_t result = getaddrinfo_a(GAI_NOWAIT, &state->gai_requests, 1, &state->sigevent); |
| 647 | + |
| 648 | + if (result != 0) |
| 649 | + { |
| 650 | + free(state); |
| 651 | + return ConvertGetAddrInfoAndGetNameInfoErrorsToPal(result); |
| 652 | + } |
| 653 | + |
| 654 | + return result; |
| 655 | +#else |
| 656 | + (void)address; |
| 657 | + (void)addressFamily; |
| 658 | + (void)entry; |
| 659 | + (void)callback; |
| 660 | + |
| 661 | + // GetHostEntryForNameAsync is not supported on this platform. |
| 662 | + return -1; |
| 663 | +#endif |
| 664 | +} |
| 665 | + |
522 | 666 | void SystemNative_FreeHostEntry(HostEntry* entry)
|
523 | 667 | {
|
524 | 668 | if (entry != NULL)
|
@@ -555,13 +699,13 @@ static inline NativeFlagsType ConvertGetNameInfoFlagsToNative(int32_t flags)
|
555 | 699 | }
|
556 | 700 |
|
557 | 701 | int32_t SystemNative_GetNameInfo(const uint8_t* address,
|
558 |
| - int32_t addressLength, |
559 |
| - int8_t isIPv6, |
560 |
| - uint8_t* host, |
561 |
| - int32_t hostLength, |
562 |
| - uint8_t* service, |
563 |
| - int32_t serviceLength, |
564 |
| - int32_t flags) |
| 702 | + int32_t addressLength, |
| 703 | + int8_t isIPv6, |
| 704 | + uint8_t* host, |
| 705 | + int32_t hostLength, |
| 706 | + uint8_t* service, |
| 707 | + int32_t serviceLength, |
| 708 | + int32_t flags) |
565 | 709 | {
|
566 | 710 | assert(address != NULL);
|
567 | 711 | assert(addressLength > 0);
|
|
0 commit comments