From ef02b0d89bdbd0307a749f4d8d3566788dc02d90 Mon Sep 17 00:00:00 2001 From: Apple Date: Tue, 29 Sep 2015 23:33:05 +0000 Subject: [PATCH] Libinfo-477.20.1.tar.gz --- Libinfo.xcodeproj/project.pbxproj | 56 ++++++++++++- lookup.subproj/getaddrinfo.3 | 71 +++++++++++++--- lookup.subproj/si_getaddrinfo.c | 130 ++++++++++++++++++++++++++++++ 3 files changed, 247 insertions(+), 10 deletions(-) diff --git a/Libinfo.xcodeproj/project.pbxproj b/Libinfo.xcodeproj/project.pbxproj index 253ab6a..d3771cc 100644 --- a/Libinfo.xcodeproj/project.pbxproj +++ b/Libinfo.xcodeproj/project.pbxproj @@ -621,7 +621,7 @@ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0440; + LastUpgradeCheck = 0700; }; buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "Libinfo" */; compatibilityVersion = "Xcode 3.2"; @@ -801,7 +801,9 @@ isa = XCBuildConfiguration; baseConfigurationReference = 3F397F7D185BD67F00987BCC /* Libinfo.xcconfig */; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; PRODUCT_NAME = info; + SUPPORTED_PLATFORMS = "macosx iphoneos"; VERSION_INFO_EXPORT_DECL = static; VERSION_INFO_PREFIX = __; }; @@ -826,6 +828,7 @@ GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; + OTHER_CFLAGS = ""; VERSIONING_SYSTEM = "apple-generic"; WARNING_LDFLAGS = "-Wall"; }; @@ -835,9 +838,56 @@ isa = XCBuildConfiguration; buildSettings = { PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = iphonesimulator; }; name = Release; }; + 90E08A3C1BB364CA0093311B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + BUILD_VARIANTS = ( + normal, + profile, + debug, + ); + CODE_SIGN_IDENTITY = "-"; + CURRENT_PROJECT_VERSION = "$(RC_ProjectSourceVersion)"; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DYLIB_CURRENT_VERSION = "$(CURRENT_PROJECT_VERSION)"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + OTHER_CFLAGS = "-DDEBUG=1"; + VERSIONING_SYSTEM = "apple-generic"; + WARNING_LDFLAGS = "-Wall"; + }; + name = Debug; + }; + 90E08A3D1BB364CA0093311B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3F397F7D185BD67F00987BCC /* Libinfo.xcconfig */; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + PRODUCT_NAME = info; + SUPPORTED_PLATFORMS = "macosx iphoneos"; + VERSION_INFO_EXPORT_DECL = static; + VERSION_INFO_PREFIX = __; + }; + name = Debug; + }; + 90E08A3E1BB364CA0093311B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = iphonesimulator; + }; + name = Debug; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -845,6 +895,7 @@ isa = XCConfigurationList; buildConfigurations = ( 1DEB914C08733D8E0010E9CD /* Release */, + 90E08A3D1BB364CA0093311B /* Debug */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -853,6 +904,7 @@ isa = XCConfigurationList; buildConfigurations = ( 1DEB915008733D8E0010E9CD /* Release */, + 90E08A3C1BB364CA0093311B /* Debug */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -861,8 +913,10 @@ isa = XCConfigurationList; buildConfigurations = ( 3F397F80185BD71500987BCC /* Release */, + 90E08A3E1BB364CA0093311B /* Debug */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/lookup.subproj/getaddrinfo.3 b/lookup.subproj/getaddrinfo.3 index abdbc09..f8b341f 100644 --- a/lookup.subproj/getaddrinfo.3 +++ b/lookup.subproj/getaddrinfo.3 @@ -131,8 +131,10 @@ or be the bitwise-inclusive OR of one or more of the values .Dv AI_NUMERICHOST , .Dv AI_NUMERICSERV , .Dv AI_PASSIVE , +.Dv AI_V4MAPPED , +.Dv AI_V4MAPPED_CFG , and -.Dv AI_V4MAPPED . +.Dv AI_DEFAULT . .Bl -tag -width "AI_CANONNAMEXX" .It Dv AI_ADDRCONFIG If the @@ -224,7 +226,7 @@ If the flag is specified along with an .Fa ai_family of -.Dv AF_INET6 , +.Dv PF_INET6 , then .Fn getaddrinfo shall return IPv4-mapped IPv6 addresses @@ -236,7 +238,20 @@ The flag shall be ignored unless .Fa ai_family equals -.Dv AF_INET6 . +.Dv PF_INET6 . +.It Dv AI_V4MAPPED_CFG +The +.Dv AI_V4MAPPED_CFG +flag behaves exactly like the +.Dv AI_V4MAPPED +flag if the kernel supports IPv4-mapped IPv6 addresses. Otherwise it is ignored. +.It Dv AI_DEFAULT +.Dv AI_DEFAULT +is defined as ( +.Dv AI_V4MAPPED_CFG +| +.Dv AI_ADDRCONFIG +). .El .El .Pp @@ -289,7 +304,7 @@ member points to a filled-in socket address structure of length This implementation of .Fn getaddrinfo allows numeric IPv6 address notation with scope identifier, -as documented in chapter 11 of draft-ietf-ipv6-scoping-arch-02.txt. +as documented in section 11 of RFC 4007. By appending the percent character and scope identifier to addresses, one can fill the .Li sin6_scope_id @@ -339,6 +354,45 @@ pointer should be an .Li addrinfo structure created by a call to .Fn getaddrinfo . +.Pp +The current implementation supports synthesis of NAT64 mapped IPv6 addresses. +If +.Fa hostname +is a numeric string defining an IPv4 address (for example, +.Dq Li 192.0.2.1 +) and +.Fa ai_family +is set to +.Dv PF_UNSPEC +or +.Dv PF_INET6, +.Fn getaddrinfo +will synthesize the appropriate IPv6 address(es) (for example, +.Dq Li 64:ff9b::192.0.2.1 +) if the current interface supports IPv6, NAT64 and DNS64 +and does not support IPv4. If the +.Dv AI_ADDRCONFIG +flag is set, the IPv4 address will be suppressed on those interfaces. +On non-qualifying interfaces, +.Fn getaddrinfo +is guaranteed to return immediately without attempting any resolution, and will +return the IPv4 address if +.Fa ai_family +is +.Dv PF_UNSPEC +or +.Dv PF_INET. +NAT64 address synthesis can be disabled by setting the +.Dv AI_NUMERICHOST +flag. To best support NAT64 networks, it is recommended to resolve all +IP address literals with +.Fa ai_family +set to +.Dv PF_UNSPEC +and +.Fa ai_flags +set to +.Dv AI_DEFAULT. .Sh RETURN VALUES .Fn getaddrinfo returns zero on success or one of the error codes listed in @@ -352,10 +406,10 @@ service via a stream socket. It loops through all the addresses available, regardless of address family. If the destination resolves to an IPv4 address, it will use an -.Dv AF_INET +.Dv PF_INET socket. Similarly, if it resolves to IPv6, an -.Dv AF_INET6 +.Dv PF_INET6 socket is used. Observe that there is no hardcoded reference to a particular address family. The code works even if @@ -475,9 +529,8 @@ freeaddrinfo(res0); .%A E. Nordmark .%A B. Zill .%T "IPv6 Scoped Address Architecture" -.%R internet draft -.%N draft-ietf-ipv6-scoping-arch-02.txt -.%O work in progress material +.%R RFC 4007 +.%D March 2005 .Re .Rs .%A Craig Metz diff --git a/lookup.subproj/si_getaddrinfo.c b/lookup.subproj/si_getaddrinfo.c index cb2fc1e..49a14c6 100644 --- a/lookup.subproj/si_getaddrinfo.c +++ b/lookup.subproj/si_getaddrinfo.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -1022,6 +1023,122 @@ _gai_srv(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint return result; } +static si_list_t * +_gai_nat64_synthesis(si_mod_t *si, const char *node, const char *serv, int numericserv, + uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface) +{ + if (NULL == node) + { + return NULL; + } + + /* validate AI_NUMERICHOST */ + if ((flags & AI_NUMERICHOST) != 0) + { + return NULL; + } + + /* validate family */ + if ((AF_UNSPEC != family) && (AF_INET6 != family)) + { + return NULL; + } + + /* validate that node is an IPv4 address */ + struct in_addr a4; + if (1 != inet_pton(AF_INET, node, &a4)) + { + return NULL; + } + + /* validate that there is at least an IPv6 address configured */ + uint32_t num_inet6 = 0; + if ((si_inet_config(NULL, &num_inet6) < 0) || (0 == num_inet6)) + { + return NULL; + } + + /* validate interface name and convert to index */ + uint32_t ifindex = 0; + if (NULL != interface) + { + ifindex = if_nametoindex(interface); + if (0 == ifindex) + { + return NULL; + } + } + + /* validate serv and convert to port */ + uint16_t port = 0; + if (0 == numericserv) + { + if (_gai_serv_to_port(serv, proto, &port) != 0) + { + return NULL; + } + else + { + flags |= AI_NUMERICSERV; + } + } + + /* query NAT64 prefixes */ + nw_nat64_prefix_t *prefixes = NULL; + const int32_t num_prefixes = nw_nat64_copy_prefixes(&ifindex, &prefixes); + if ((num_prefixes <= 0) || (NULL == prefixes)) + { + return NULL; + } + + /* add every address to results */ + si_list_t *out_list = NULL; + for (int32_t i = 0; i < num_prefixes; i++) + { + struct in6_addr a6; + if (!nw_nat64_synthesize_v6(&prefixes[i], &a4, &a6)) + { + continue; + } + si_list_t *temp_list = si_addrinfo_list(si, flags, socktype, proto, NULL, &a6, port, (int)ifindex, NULL, NULL); + if (NULL == temp_list) + { + continue; + } + if (NULL != out_list) + { + out_list = si_list_concat(out_list, temp_list); + si_list_release(temp_list); + } + else + { + out_list = temp_list; + } + } + + free(prefixes); + + /* return to standard code path if no NAT64 addresses could be synthesized */ + if (NULL == out_list) + { + return NULL; + } + + /* add IPv4 addresses and IPv4-mapped IPv6 addresses if appropriate */ + if (((AF_UNSPEC == family) && ((flags & AI_ADDRCONFIG) == 0)) || + ((AF_INET6 == family) && ((flags & AI_ALL) != 0) && ((flags & AI_V4MAPPED) != 0))) + { + si_list_t *list4 = si_addrinfo_list(si, flags, socktype, proto, &a4, NULL, port, (int)ifindex, NULL, NULL); + if (NULL != list4) + { + out_list = si_list_concat(out_list, list4); + si_list_release(list4); + } + } + + return _gai_sort_list(out_list, flags); +} + si_list_t * si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err) { @@ -1099,6 +1216,12 @@ si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, u return NULL; } + /* replace AI_V4MAPPED_CFG with AI_V4MAPPED */ + if ((flags & AI_V4MAPPED_CFG) != 0) + { + flags = (flags & ~AI_V4MAPPED_CFG) | AI_V4MAPPED; + } + /* check AI_V4MAPPED and AI_ALL */ if (family != AF_INET6) { @@ -1152,6 +1275,13 @@ si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, u } } + /* NAT64 IPv6 address synthesis support */ + si_list_t *nat64_list = _gai_nat64_synthesis(si, node, serv, numericserv, family, socktype, proto, flags, interface); + if (NULL != nat64_list) + { + return nat64_list; + } + numerichost = _gai_numerichost(node, &family, flags, &a4, &a6, &scope); if ((numerichost == -1) || ((flags & AI_NUMERICHOST) && (numerichost == 0))) { -- 2.47.2