Using HTTPDNS in iOS native scenarios
This topic describes how to implement a direct IP connection when you integrate HTTPDNS into an iOS app. For more information about how to integrate HTTPDNS on iOS, see iOS SDK integration.
1. Introduction
In mobile network environments, issues such as DNS hijacking and local DNS cache pollution often prevent domain names from resolving correctly, which leads to network request failures. For these scenarios, Alibaba Cloud HTTPDNS provides a reliable recursive domain name resolution service. This service helps mobile apps bypass the potential risks of local DNS and improves the success rate and stability of network requests.
However, using HTTPDNS on the iOS platform requires you to replace the original domain name in a request with the resolved IP address before you initiate the request. This can cause additional issues, especially in complex scenarios such as HTTPS and Server Name Indication (SNI). Therefore, before you integrate HTTPDNS, you must have a comprehensive understanding of the potential issues and viable solutions. This ensures that you can use HTTPDNS safely and correctly in your business.

This topic describes the main issues that you may encounter when using HTTPDNS on iOS. It also provides integration solutions for different scenarios, along with their pros and cons, to help developers quickly complete HTTPDNS integration.
2. Issues when using HTTPDNS on iOS
In mobile applications, if you replace the domain name in the original URL, such as example.com, with the IP address resolved by HTTPDNS, you often encounter the following issues. These problems are closely related to how the HTTPS protocol uses the Host field at different layers: the TLS/SSL layer and the HTTP layer.
TLS/SSL layer: In an HTTPS scenario, the client first performs a TLS/SSL handshake. The client uses the Host from the URL to complete the following tasks:
Certificate verification: Verifies that the domain name of the server certificate (Common Name or Subject Alternative Name) matches the requested Host.
SNI: When establishing a TLS connection, the client sends the requested domain name information (the Host in the URL) to the server. This allows the server to return the corresponding certificate.
HTTP layer: After the TLS handshake is complete, the client includes the
Hostfield in the HTTP request header. This tells the server the specific site or resource for the request. If you replace the domain name in the URL with an IP address and do not manually set theHostin the HTTP header, the server may not be able to identify the actual domain name being accessed. This can cause the request to fail or return abnormal content.
Based on the role of the Host at various layers of the HTTPS protocol stack, replacing the domain name in the URL with the IP address resolved by HTTPDNS causes the following technical issues:
Domain name and certificate mismatch For an HTTPS request, if you directly use the IP address resolved by HTTPDNS as the Host in the URL, the TLS layer cannot match the correct certificate domain name (Common Name or SAN additional domain name). This causes the SSL handshake to fail.
SNI issues In an SNI scenario, a single server IP address may correspond to certificates for multiple domain names. If the client does not pass the correct domain name information during the SSL handshake phase and sends only the IP address, the server cannot return a certificate that matches the domain name. This causes the SSL handshake to fail. Because high-level network APIs in iOS, such as
NSURLSession, do not expose an interface to directly configure SNI, SNI issues are often difficult to solve with simple methods.Host header and service addressing If you replace the domain name in the URL with an IP address but forget to explicitly set the
Hostin the HTTP request header to the original domain name, the server-side may not be able to identify the specific site or resource at the HTTP layer. For example, in a CDN scenario, the server relies on the Host field to distribute the correct content. If the Host is an IP address, the service becomes abnormal.Choice of underlying network library The built-in high-level APIs in iOS, such as
NSURLSession, have limited extensibility for customizing SNI or manual certificate verification. If a developer wants to handle SNI or modify the TLS handshake logic, they need to use lower-level interfaces, such asCFNetworkorlibcurl. However, this increases development and maintenance costs.
In summary, directly replacing the domain name in a URL with the IP address resolved by HTTPDNS affects certificate verification and SNI transmission at the TLS layer in HTTPS scenarios. It may also cause Host header information to be abnormal at the HTTP layer. Therefore, when you integrate HTTPDNS on iOS, you must solve these issues in a targeted manner to ensure the reliability and security of network requests.
3. Recommended solution: Integrate with EMASCurl
In real-world iOS applications, HTTPS is standard, and scenarios involving CDNs, single IPs for multiple domains, and SNI are common. To address these challenges, the Alibaba Cloud EMAS team provides EMASCurl, an iOS network library built on libcurl. It works directly with HTTPDNS and is the recommended solution for implementing a direct IP connection on iOS. The code is open-source and available on GitHub.
This section describes the use cases, integration approach, and usage notes for the EMASCurl solution. For specific installation instructions, interception configurations, and API usage, see the README file on GitHub.
Installation and interception
It can be used in two main ways:
1) Intercept requests from an
NSURLSessioncreated with a specificNSURLSessionConfiguration.2) Intercept requests from the system's global
[NSURLSession sharedSession].
Integration with HTTPDNS
Implement the
EMASCurlProtocolDNSResolverprotocol to pass the HTTPDNS resolution results to EMASCurl.In the
resolveDomain:method, call[HttpDnsService resolveHostSyncNonBlocking:]to get the IP address. Then, return it to EMASCurl to handle the SNI setup and send the request.
Certificate verification
EMASCurl relies on the certificate verification mechanism of
libcurl. You can also extend or customize certificate verification through the provided interfaces to meet your service requirements.
HTTP/3 support
EMASCurl provides EMASCurl/HTTP3, an encapsulated version based on a QUIC-enabled
libcurl. You can integrate it as needed to use HTTP/3 capabilities without extra adaptation.
The following example shows the basic method for integrating EMASCurl with HTTPDNS:
@interface MyDNSResolver : NSObject <EMASCurlProtocolDNSResolver>
@end
@implementation MyDNSResolver
+ (nullable NSString *)resolveDomain:(nonnull NSString *)domain {
HttpDnsService *httpdns = [HttpDnsService sharedInstance];
HttpdnsResult *result = [httpdns resolveHostSyncNonBlocking:domain
byIpType:HttpdnsQueryIPTypeBoth];
if (!result || (!result.hasIpv4Address && !result.hasIpv6Address)) {
return nil;
}
NSMutableArray<NSString *> *allIPs = [NSMutableArray array];
if (result.hasIpv4Address) {
[allIPs addObjectsFromArray:result.ips];
}
if (result.hasIpv6Address) {
[allIPs addObjectsFromArray:result.ipv6s];
}
return [allIPs componentsJoinedByString:@","];
}
@end
- (void)setupEMASCurl {
EMASCurlConfiguration *config = [EMASCurlConfiguration defaultConfiguration];
// Configure the HTTPDNS resolver
config.dnsResolver = [MyDNSResolver class];
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
// Install EMASCurl
[EMASCurlProtocol installIntoSessionConfiguration:sessionConfig
withConfiguration:config];
// Create a specific session
self.session = [NSURLSession sessionWithConfiguration:sessionConfig];
// Use this session for subsequent requests
}Pros:
It encapsulates the underlying capabilities of
libcurlwith an API that is familiar to iOS developers.It easily integrates with HTTPDNS through a DNS hook mechanism.
It solves both the domain transmission and certificate verification issues in SNI scenarios, which reduces integration cost.
It supports HTTP/3 out of the box and does not require custom compilation or adaptation.
Cons:
It depends on a third-party library (EMASCurl and libcurl). You must consider compatibility and version upgrades.
For complex HTTP features or custom requirements, you may need to understand EMASCurl's internal implementation to ensure service availability.
When you integrate EMASCurl, test common HTTP/HTTPS features, such as redirection, cookies, and concurrent requests, to ensure that they meet your service requirements.
If your business has strict security or network performance requirements, evaluate the performance of EMASCurl on your current iOS version.
Ensure that requests and handshakes complete normally in different network environments, such as Wi-Fi, cellular networks, and proxies.
4. Integration solutions for simplified scenarios
For plain HTTP or HTTPS without SNI scenarios, you can typically continue to use the system's built-in NSURLSession and regular network request logic to integrate HTTPDNS with simple adjustments. These solutions are simpler to implement, suitable for specific scenarios, and have limited applicability.
Note that plain HTTP scenarios do not involve a TLS handshake or certificate verification. However, HTTPS without SNI scenarios still require you to handle certificate verification, which you can do by hooking the verification process in NSURLSession.
4.1 Plain HTTP scenarios
For plain HTTP requests, there is no TLS/SSL handshake or certificate verification. Therefore, the core operations for integrating HTTPDNS occur only at the HTTP layer:
Replace the Host in the request URL with the IP address from HTTPDNS
For example, if the original request URL is
http://example.com/apiand HTTPDNS resolves it to the IP address1.2.3.4, change the URL tohttp://1.2.3.4/api.
Explicitly set the
Hostheader to the original domainIf you use
NSMutableURLRequest, you can addrequest.allHTTPHeaderFields[@"Host"] = @"example.com";to the request header. This ensures that the server can identify the correct domain at the application layer.
Pros: Simple to implement. It only requires replacing the Host and setting the header in the existing HTTP request, with minimal development effort.
Cons: Only applicable to plain HTTP. It cannot solve certificate verification and SNI-related issues in HTTPS scenarios.
4.2 HTTPS scenarios without SNI
For HTTPS sites that do not use SNI or that have only a few fixed domains covered by their certificate, you can integrate HTTPDNS and perform certificate verification at the NSURLSession layer as follows:
Replace the Host in the request URL with the IP address from HTTPDNS
For example, if the original request URL is
https://example.com/apiand HTTPDNS resolves it to the IP address1.2.3.4, change the URL tohttps://1.2.3.4/api.
Explicitly set the
Hostheader to the original domainSimilarly, you can set
request.allHTTPHeaderFields[@"Host"] = @"example.com";inNSMutableURLRequest.
Hook the certificate verification process
Because this is an HTTPS request, certificate verification is required during the TLS handshake. At this point, using the IP address as the Host for verification will cause a domain and certificate mismatch.
In the
NSURLSessionDelegatecallback methodURLSession:didReceiveChallenge:completionHandler:, you can replace the IP address with the original domain (example.com) when you verify theserverTrustobtained from the system. This allows the certificate verification to pass.Code example:
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { NSString *originalHost = [self getOriginalHostFromRequest:task.originalRequest]; SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; if ([self evaluateServerTrust:serverTrust forDomain:originalHost]) { // The certificate is verified. NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust]; completionHandler(NSURLSessionAuthChallengeUseCredential, credential); } else { // Certificate verification failed. Use the default handler. completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); } } else { completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); } } - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain { // Create a certificate verification policy. NSMutableArray *policies = [NSMutableArray array]; if (domain) { [policies addObject:(__bridge_transfer id) SecPolicyCreateSSL(true, (__bridge CFStringRef) domain)]; } else { [policies addObject:(__bridge_transfer id) SecPolicyCreateBasicX509()]; } // Bind the verification policy to the server certificate. SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef) policies); // Evaluate whether the current serverTrust is trusted. Apple recommends that the serverTrust can be verified if the result is kSecTrustResultUnspecified or kSecTrustResultProceed. For more information, see https://developer.apple.com/library/ios/technotes/tn2232/_index.html. // For more information about SecTrustResultType, see SecTrust.h. SecTrustResultType result; SecTrustEvaluate(serverTrust, &result); return (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed); }
Pros:
You can use the native
NSURLSessionand its certificate verification logic without adding a third-party library.The implementation cost is manageable, which makes it suitable for scenarios that do not involve SNI or require only a few domain certificates.
Cons:
This approach does not handle SNI scenarios. If multiple domains are deployed on the same IP address, such as in a CDN scenario, the handshake still fails because the server returns the wrong certificate.
5. Other solutions for HTTPS + SNI scenarios
For HTTPS + SNI scenarios, besides EMASCurl, you can also implement HTTPDNS integration by using lower-level capabilities. These solutions typically offer greater flexibility but come with higher development and maintenance costs. They are better suited for scenarios with existing custom network stacks, a need for stronger low-level control, or cross-platform unification requirements. If you do not have special requirements, we recommend using the EMASCurl solution.
5.1 Custom NSURLProtocol
iOS allows you to intercept network requests initiated by the system by subclassing NSURLProtocol and then implementing the HTTP/HTTPS request logic yourself at a lower level. You can manually complete all network operations by using interfaces such as CFNetwork or NSInputStream/NSOutputStream:
Intercept requests
In the
canInitWithRequest:method, determine whether to intercept the current request.In the
startLoadingmethod, replace the domain in the original request URL with the IP address. You must retain the original domain for subsequent certificate verification and SNI settings.
Set SNI
Use
CFStream-related APIs or theSecureTransportinterface to specifykCFStreamSSLPeerNameas the original domain. This ensures that the underlying layer includes the correct domain information during the SSL handshake.
Verify certificates
Manually execute the certificate verification process to ensure that the domain included in the certificate matches the original domain.
Pros: Does not depend on a third-party library. It is based entirely on low-level system APIs and offers high flexibility.
Cons: High implementation cost. You must manually handle redirection, cookies, caching, encoding, and traffic statistics. It does not support connection reuse, which results in average performance. It also carries a high maintenance risk and requires extra adaptation when the system or network environment is upgraded.
For a reference example, Alibaba Cloud EMAS provides a sample implementation named HttpDnsNSURLProtocolImpl.m in the httpdns_ios_demo. You can modify or reuse it based on your service requirements.
5.2 Using libcurl
libcurl is a cross-platform network library implemented in C. It supports manually setting the SNI field to pass the correct domain information during the SSL handshake. This is required for certificate verification in scenarios where multiple domains share the same IP address. The general process is as follows:
Resolve the domain to get the corresponding IP address
For example, use an HTTPDNS API method such as
resolveHostSyncNonBlocking:to get the IP address of the target domain.
Set the SNI and IP mapping
Use
CURLOPT_RESOLVEor another API to write the "domain:port:resolved_IP" mapping to curl's internal DNS cache.Continue to use the original domain for
CURLOPT_URL. This ensures that the correct domain information is included in the TLS handshake.
Verify certificates
libcurlenables certificate verification by default. You can also use corresponding callbacks for more fine-grained checks on certificates as needed.
The following code snippet (pseudocode) demonstrates how to use the HTTPDNS resolution result with libcurl to complete a request in iOS:
CURL *curl_handle = curl_easy_init();
if (curl_handle) {
// For example, get IP = 1.2.3.4 from HTTPDNS, target domain = example.com, and port = 443
struct curl_slist *dnsResolve = NULL;
dnsResolve = curl_slist_append(dnsResolve, "example.com:443:1.2.3.4");
// Set the domain-to-IP mapping
curl_easy_setopt(curl_handle, CURLOPT_RESOLVE, dnsResolve);
// Continue to use the original domain as the URL
curl_easy_setopt(curl_handle, CURLOPT_URL, "https://example.com");
// Enable SSL verification
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 1L);
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 2L);
// Initiate the request
CURLcode res = curl_easy_perform(curl_handle);
// Check the result
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
}
// Clean up
curl_easy_cleanup(curl_handle);
curl_slist_free_all(dnsResolve);
}Pros:
Mature and stable, supports a rich set of protocols, and can adapt to complex network environments. It has built-in support for SNI scenarios.
Cons:
Requires compiling
libcurlinto the iOS project and using a pure C interface, which has a learning curve for Objective-C/Swift developers.You must also handle custom request flows or encapsulate HTTP logic, such as for cookies, redirection, and caching.
6. Summary
You can choose a solution based on your business needs, such as whether you need to support SNI, multiple domain names, and certificate verification. The following table compares the different solutions:
Solution | Scenarios | Pros | Cons |
EMASCurl (Recommended) | All scenarios For simple integration on iOS | - Provides a good wrapper for libcurl - Simple integration with HTTPDNS - Implements SNI and certificate verification - Supports HTTP/3 | - Depends on a third-party library, requires attention to compatibility and upgrades - Special requirements may require reading the source code for customization |
Set Host and Header only | Plain HTTP scenarios | - Lowest integration cost | - Only for plain HTTP protocol |
NSURLSession + Hook certificate verification (Still requires setting Host and Header) | HTTPS (non-SNI) scenarios | - Low integration cost - Uses system APIs, no extra libraries needed | - Does not support SNI |
Custom NSURLProtocol | All scenarios Requires more flexible low-level control | - Completely based on low-level system APIs - High flexibility | - High development and maintenance costs - No connection reuse, average performance - Requires manual handling of redirection, cookies, caching, encoding, and other special cases |
libcurl | All scenarios Cross-platform or custom HTTP flows | - Mature and stable - Supports SNI field setting and rich protocols - Flexible certificate verification extension | - C interface has a learning curve for Objective-C/Swift developers - Requires manual encapsulation for cookies, redirection, caching, etc. |
You can evaluate these solutions based on your business's multi-domain needs, network security requirements, compatibility, maintenance costs, and acceptance of third-party libraries. You must choose the most suitable integration solution and thoroughly test the availability and security of network requests before the solution is published.