Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement simultaneous DNS resolution #19

Merged
merged 1 commit into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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")
)
]
```
Expand Down
57 changes: 49 additions & 8 deletions SNASources/CellularSession.m
Original file line number Diff line number Diff line change
Expand Up @@ -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<SocketAddress *> *localAddresses = [NSMutableArray array];
// All remote IP addresses that we're trying to connect to.
Expand Down Expand Up @@ -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)
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion Sources/TwilioVerifySNAConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
import Foundation

public struct TwilioVerifySNAConfig {
public static let version = "0.0.7"
public static let version = "0.0.8"
}
Original file line number Diff line number Diff line change
Expand Up @@ -398,4 +398,4 @@ extension PhoneNumberViewController {
}

/// Not required for the SDK implementation.
private let sampleAppVersion = "0.0.7"
private let sampleAppVersion = "0.0.8"
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "";
Expand Down Expand Up @@ -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 = "";
Expand Down
Loading