These are not contradictory given the presence of the “Where Possible” qualifier. In fact, that section of the docs (Avoid POSIX Sockets and CFSocket on iOS Where Possible) goes on to say that a key advantage of BSD Sockets is that you can “support protocols other than TCP”.
It’s generally true that, when you use UDP, you get greater flexibility but that comes at the cost of requiring your to do more work. iOS is no exception in this regard. iOS has lots of smarts in its connect-by-name subsystem, and UDP can’t take advantage of that because it doesn’t support a ‘connect’ operation.
I’ll address your specific concerns in the sections below.
With regards IPv6, there are no real obstacles to you supporting IPv6 in BSD Sockets-based UDP code. Your code won’t be as smart as the connect-by-name subsystem makes TCP, but it should work just fine.
IIRC the specific IPv6-related smarts that you miss out on are:
RTT-based address choice — If the DNS server returns multiple addresses for a given name, the connect-by-name subsystem uses round trip time information from the routing table to decide what address to try first. You don’t have access to the information needed to do that. Instead, you should do the standard BSD Sockets thing, that is, call
getaddrinfo
and use the addresses in the order that it returns.try addresses until things work — If the DNS server returns multiple addresses for a given name, the connect-by-name subsystem will try all of the addresses until if finds one that works. This makes it very easy for the app to do the right thing in the presence of multiple IPv4 and IPv6 addresses, some of which might not worked in the current network environment (due to router misconfiguration, firewalls, and so on). BSD Sockets code has to do this retrying itself. For UDP this requirement is unavoidable because there’s no standard definition of works.
IPv4 literal addresses in NAT64 networks — As mentioned in the docs you quoted, this only works for high-level APIs. However, you shouldn’t be using literal IP addresses, but rather DNS, so this doesn’t matter.
With regards VPN On Demand, UDP’s lack of a ‘connect’ operation makes it impossible for it to integrate with the VPN On Demand system. This isn’t about APIs, but about the fundamental on-the-wire semantics of the protocol.
Note It’s important to realise that the VPN On Demand system is not traffic based. This was a deliberate design decision on our part, because traffic-based transient links tend to suffer from many false positives.
You can game the VPN On Demand system by using a dummy TCP connection to force the VPN to come up. I generally don’t recommend this (hey, I generally don’t recommend UDP!) but you wouldn’t be the first developer to go down that path.
Finally, I have to say that these problems are relatively minor compared to the issues required to make UDP work in general. There are lots of environments where using UDP anywhere outside of the local link just won’t work. For example:
anyone behind an HTTP proxy isn’t going to be able to use UDP
many corporate firewalls block UDP
NATs and UDP are not good friends; you can make them play well together in many, but not all, cases
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"