API to open a socket on a specific interface

Does CFNetwork provide API to open a socket on a particular interface? This post suggests

using SCNetworkInterfaceCopyAll and SCNetworkInterfaceGetInterfaceType to find an interface with a desired type. But I get an error saying SCNetworkInterfaceCopyAll is unavailable in Xcode 8.3.2.


If SCNetworkInterfaceCopyAll is unavailable, how would you search the result of getifaddrs to find an interface with a type (e.g. kSCNetworkInterfaceTypeIEEE80211 (wifi) vs kSCNetworkInterfaceTypeWWAN (cell)).


Thanks!

Answered by DTS Engineer in 226101022

I'm working on iOS.

OK then, the System Configuration framework APIs you’re referencing are only available on macOS.

This issue breaks down as follows:

  • Binding a connection to an interface

  • Selecting an interface.

I’ll discuss each in turn.

If you’re working with low-level APIs — those that let you get at the socket (in the BSD Sockets sense) for the connection — you can force the connection to run over a specific interface in two ways:

  • By using

    bind
    to bind the source address of the socket to the interface’s IP address
  • Using the

    IP_BOUND_IF
    socket option

This works well for BSD Sockets and things tightly tied to it (like CFSocket and GCD). It does not work at all for higher-level APIs, like NSURLSession. You can bodgy it into working for CFSocketStream, but that has some serious caveats.

With regards identifying an interface, iOS doesn’t have any really good options on that front. You can call

getifaddrs
to get an interface list and then, for
AF_LINK
interfaces, muddle around in
struct if_data
, but there are some serious drawbacks:
  • The constants needed to test

    ifi_type
    are not part of the iOS SDK, and hence not officially supported
  • Even when you identify the interface type, you’ll find that there are often multiple active interfaces of each type and there’s no supported way to pick between them

What’s your high-level goal here? Specific subsystems within iOS have supported ways to run connections over a specific interface, so there might be a subsystem-specific mechanism that can help you out. For example, captive network apps can force the connection to run over the captive Wi-Fi interface by calling

-bindToHotspotHelperCommand:
.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I am trying to concurrently direct traffic out through either wifi or cellular within Packet Tunnel Provider

I am trying to concurrently direct traffic out through either wifi or cellular within Packet Tunnel Provider

Networking within packet tunnel providers is a very different kettle of fish. I recommend that you open a new thread, tagging it with NetworkExtension to make sure that Matt sees it.

Share and Enjoy

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

API to open a socket on a specific interface
 
 
Q