diff --git a/CHANGELOG.md b/CHANGELOG.md index 345c2ae..f9f2b2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +# 0.0.8 (12–06-2024) + +### Improvements + +- Implement simultaneous DNS resolution to address scenarios where an IP version DNS could take too long to time out due to unavailability + +# 0.0.7 (3–05-2024) + +### Improvements + +- Add Privacy Manifest + +# 0.0.6 (07–04-2024) + +### Improvements + +- Use GET & HTTP version 1.1 for Cellular requests, and forcing IPv4 resolution before try IPv6 + # 0.0.5 (02–02-2024) ### Improvements diff --git a/README.md b/README.md index 69a9240..3af35eb 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ During the current phase of this project, we only support SPM. We have plans to dependencies: [ .package( url: "https://github.com/twilio/twilio-verify-sna-ios.git", - .upToNextMajor(from: "0.0.7") + .upToNextMajor(from: "0.0.8") ) ] ``` diff --git a/SNASources/CellularSession.m b/SNASources/CellularSession.m index 39706ad..fa1f6a5 100644 --- a/SNASources/CellularSession.m +++ b/SNASources/CellularSession.m @@ -51,8 +51,8 @@ - (CellularSessionResult * _Nonnull)performRequest:(NSURL * _Nonnull)url { sessionResult.status = CellularSessionUnexpectedError; // Stores any errors that occur during execution - OSStatus status; - + __block OSStatus status; + // All local (cellular interface) IP addresses of this device. NSMutableArray *localAddresses = [NSMutableArray array]; // All remote IP addresses that we're trying to connect to. @@ -103,7 +103,7 @@ - (CellularSessionResult * _Nonnull)performRequest:(NSURL * _Nonnull)url { ifaddrs = ifaddrs->ifa_next; } - struct addrinfo *addrinfoPointer; + __block struct addrinfo *addrinfoPointer; struct addrinfo *addrinfo; // Generate "hints" for the DNS lookup (namely, search for both IPv4 and IPv6 addresses) @@ -127,12 +127,53 @@ - (CellularSessionResult * _Nonnull)performRequest:(NSURL * _Nonnull)url { DNSServiceRef sdRef = NULL; DNSServiceFlags flags = kDNSServiceFlagsTimeout; // Set flags as needed - status = cellular_getaddrinfo([[url host] UTF8String], service, &hints, &addrinfoPointer, sdRef, flags, kDNSServiceProtocol_IPv4); + dispatch_group_t group = dispatch_group_create(); + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + __block BOOL resolutionCompleted = NO; + __block struct addrinfo *addrinfoIPv4 = NULL; + __block struct addrinfo *addrinfoIPv6 = NULL; - if (status || addrinfoPointer == NULL) { - // Retry DNS resolution with IPV6 - status = cellular_getaddrinfo([[url host] UTF8String], service, &hints, &addrinfoPointer, sdRef, flags, kDNSServiceProtocol_IPv6); - } + // Start the IPv4 resolution + dispatch_group_async(group, queue, ^{ + status = cellular_getaddrinfo([[url host] UTF8String], service, &hints, &addrinfoIPv4, sdRef, flags, kDNSServiceProtocol_IPv4); + if (status == 0 && addrinfoIPv4 != NULL) { + @synchronized (semaphore) { + if (!resolutionCompleted) { + addrinfoPointer = addrinfoIPv4; + resolutionCompleted = YES; + dispatch_semaphore_signal(semaphore); + } + } + } + }); + + // Start the IPv6 resolution + dispatch_group_async(group, queue, ^{ + status = cellular_getaddrinfo([[url host] UTF8String], service, &hints, &addrinfoIPv6, sdRef, flags, kDNSServiceProtocol_IPv6); + if (status == 0 && addrinfoIPv6 != NULL) { + @synchronized (semaphore) { + if (!resolutionCompleted) { + addrinfoPointer = addrinfoIPv6; + resolutionCompleted = YES; + dispatch_semaphore_signal(semaphore); + } + } + } + }); + + // Wait for the first resolution to complete + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + + // Clean up the other addrinfo if it was also resolved + dispatch_group_notify(group, dispatch_get_main_queue(), ^{ + if (addrinfoIPv4 && addrinfoIPv4 != addrinfoPointer) { + freeaddrinfo(addrinfoIPv4); + } + if (addrinfoIPv6 && addrinfoIPv6 != addrinfoPointer) { + freeaddrinfo(addrinfoIPv6); + } + }); if (status || addrinfoPointer == NULL) { freeifaddrs(ifaddrPointer); diff --git a/Sources/TwilioVerifySNAConfig.swift b/Sources/TwilioVerifySNAConfig.swift index eff8070..0edd7b4 100644 --- a/Sources/TwilioVerifySNAConfig.swift +++ b/Sources/TwilioVerifySNAConfig.swift @@ -20,5 +20,5 @@ import Foundation public struct TwilioVerifySNAConfig { - public static let version = "0.0.7" + public static let version = "0.0.8" } diff --git a/TwilioVerifySNADemo/Screens/PhoneNumber/PhoneNumberViewController.swift b/TwilioVerifySNADemo/Screens/PhoneNumber/PhoneNumberViewController.swift index 899ffab..e1739f9 100644 --- a/TwilioVerifySNADemo/Screens/PhoneNumber/PhoneNumberViewController.swift +++ b/TwilioVerifySNADemo/Screens/PhoneNumber/PhoneNumberViewController.swift @@ -398,4 +398,4 @@ extension PhoneNumberViewController { } /// Not required for the SDK implementation. -private let sampleAppVersion = "0.0.7" +private let sampleAppVersion = "0.0.8" diff --git a/TwilioVerifySNADemo/TwilioVerifySNADemo.xcodeproj/project.pbxproj b/TwilioVerifySNADemo/TwilioVerifySNADemo.xcodeproj/project.pbxproj index 3d4aa6c..e56c583 100644 --- a/TwilioVerifySNADemo/TwilioVerifySNADemo.xcodeproj/project.pbxproj +++ b/TwilioVerifySNADemo/TwilioVerifySNADemo.xcodeproj/project.pbxproj @@ -417,7 +417,7 @@ "@executable_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.0; - MARKETING_VERSION = 0.0.7; + MARKETING_VERSION = 0.0.8; PRODUCT_BUNDLE_IDENTIFIER = com.twilio.TwilioVerifySNADemo; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -448,7 +448,7 @@ "@executable_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.0; - MARKETING_VERSION = 0.0.7; + MARKETING_VERSION = 0.0.8; PRODUCT_BUNDLE_IDENTIFIER = com.twilio.TwilioVerifySNADemo; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "";