How to Resolve DNS via Cellular Network

Hello everyone,

Are there any APIs on iOS to resolve DNS via Cellular network when WiFi is also connected? As I connect my iPhone to WiFi, DNS will be resolved via WiFi not Cellular.

Low level APIs are preferred.

Thanks!
Answered by DTS Engineer in 666761022

The network stack is cross-platform

OK, well, I guess that rules out all the easy solutions )-:

If there is a high-level API that only deal with the DNS on
multi-network, it's also great.

Apple platforms don’t have high-level DNS APIs because we strongly encourage developers to use one of our connect-by-name APIs. The whole resolve-then-connect approach promulgated by BSD Sockets is fundamentally flawed:
  • On Apple platforms specifically, the networking stack needs to know about your intention to connect in order to react appropriately. For example, early versions of iOS would shut down the WWAN when it was idle. When a client tried to connect to a DNS name on the other side of the WWAN interface, the system would bring it up automatically. However, it’s not appropriate to do that at the resolve step. This strategy has long since fallen by the wayside, we now keep the WWAN interface up where possible, but the same infrastructure is still used in a wide variety of other places on our platforms.

  • Even on non-Apple platforms, a best-of-class Happy Eyeballs implementation is really frikkin’ hard.

So, if you’re going to do your own resolution you’ll end up using a low-level API. The most flexible of these is <dns_sd.h>. It has a resolve call, DNSServiceGetAddrInfo, that takes a specific interface. I have used this in the past to do various weird things, but I’ve never used it to try to force the resolve to work over WWAN. You should give it a try and see how you get along.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Are there any APIs on iOS to resolve DNS via Cellular network when
Wi-Fi is also connected?

This is a pretty unusual requirement. Can you explain some of the backstory here?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
My APP needs to send HTTP request via Cellular while WiFi is connected. I can use setsockopt and IP_BOUND_IF to bind low level socket that sends request data with Cellular interface. But I have no idea how to bind DNS resolving to Cellular.

If I use getaddrinfo, DNS resolving will go through WiFi by default, and the result is not what I want.
I’m still confused. Why do you expect the WWAN DNS to return different results than the Wi-Fi DNS?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
The network operator companies of WWAN and WiFi are different. As far as I know, the server end's access point(such as an AWS Gateway) IPs maybe different in different operators' network. For example, if I resolve DNS under Cellular, it will return the IPs of access point in Cellular operator's network.

In order to get a shortest path and good network performance, it is not recommended to connect WiFi operator's access point when the APP is using Cellular to send request.

Emmmm, and another situation is considered: When the WiFi network is poor, I need my APP to send request via Cellular, as well as DNS resolving request.
Are you using BSD Sockets for this? If so, is that an irrevocable design decision?

The reason I ask is that you might be better off simply switching to the Network framework. It’s already doing this sort of low-level shenanigans to optimise the network performance and, while it’s easy to ‘beat’ it in some circumstances, it’s hard to do better in the wide range of network conditions that iOS device encounter.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Yes, my APP's network stack is implemented on BSD Sockets. The network stack is cross-platform, also works on Android, and I have done a lot of works to optimize it. iOS Network framework is convenient, but I have no choice in this circumstance.

Does it seem that there is no low-level API on iOS to handle the DNS resolving work mentioned above? If there is a high-level API that only deal with the DNS on multi-network, it's also great.
Accepted Answer

The network stack is cross-platform

OK, well, I guess that rules out all the easy solutions )-:

If there is a high-level API that only deal with the DNS on
multi-network, it's also great.

Apple platforms don’t have high-level DNS APIs because we strongly encourage developers to use one of our connect-by-name APIs. The whole resolve-then-connect approach promulgated by BSD Sockets is fundamentally flawed:
  • On Apple platforms specifically, the networking stack needs to know about your intention to connect in order to react appropriately. For example, early versions of iOS would shut down the WWAN when it was idle. When a client tried to connect to a DNS name on the other side of the WWAN interface, the system would bring it up automatically. However, it’s not appropriate to do that at the resolve step. This strategy has long since fallen by the wayside, we now keep the WWAN interface up where possible, but the same infrastructure is still used in a wide variety of other places on our platforms.

  • Even on non-Apple platforms, a best-of-class Happy Eyeballs implementation is really frikkin’ hard.

So, if you’re going to do your own resolution you’ll end up using a low-level API. The most flexible of these is <dns_sd.h>. It has a resolve call, DNSServiceGetAddrInfo, that takes a specific interface. I have used this in the past to do various weird things, but I’ve never used it to try to force the resolve to work over WWAN. You should give it a try and see how you get along.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

we now keep the WWAN interface up where possible

It's a good decision. I don't need to bring WWAN up when WiFi is connected. But I have to do this on Android :-(

Even on non-Apple platforms, a best-of-class Happy Eyeballs implementation is really frikkin’ hard.

Agree.

Low-level APIs are not that friendly, and it's a bit challenging to develop on them :-)

Thanks buddy! You helped me a lot.

Hey, I think I'm in the exactly same situation like you (9 months ago). Did you find any good solution about this? Or can you share what you did?

I'm in the same boat. I have a port knocking app that requires sending low-level packets. DNS resolution is something I need to do before I can use the typical socket() calls. Looks like CFHostGetAddressing is now deprecated, and not a lot of alternatives. I'll see if DNSServiceGetAddrInfo can work for me. I understand it's not a common use-case, but it's been an app that continues to get usage, so clearly there's a need.

How to Resolve DNS via Cellular Network
 
 
Q