Create SIP, RTP, SRTP, RTCP connection with LTE over WiFi

Dear Concern,

We have developed module to create HTTP, SIP, RTP, SRTP, RTCP and MBCP connection with server based C/C++ based network api included in net/if.h, neinet/tcp.h etc.


We want to force all of our network traffics(HTTP, SIP, RTP, SRTP, RTCP, MBCP) through LTE, even iPhone has a connection with WiFi.


With NWParameter,

let parameters = NWParameters(tls: options)
parameters.prohibitedInterfaceTypes = [.wifi] 


After that, We have to create NWconnection

guard let endPoint = NWEndpoint.Port(rawValue: 4420) else {  
  return  
  }  
  
  con = NWConnection(to: .hostPort(host: NWEndpoint.Host("somehostname.com"), port: endPoint), using: parameters) 

This works in some HTTP request. Is there any way in native api where we can block the WiFi interface and transfer all traffic through LTE?

Or any generic api which will block WiFi for that specific app?


Because, If WiFi is enabled, by default, we are only reachable to WiFi and getting ip address of WiFi interface.


Best regards

Arup Sarker

arupcsedu@gmail.com

First up, terminology. I’m not entirely sure what you mean by “native api” but I suspect you’re referring to BSD Sockets, that is,

socket
,
bind
,
connect
, and so on.

If so, you’re use of the term “native api” suggest a serious misunderstanding of the iOS network architecture. The Network framework is not a wrapper around the ‘native’ BSD Sockets API [1]. Rather, iOS has two networking stacks, one inside the kernel and one running in user space. BSD Sockets runs through the in-kernel stack and Network framework runs through the user space one. In most cases the user space stack is faster, and that’s one of the reasons we recommend that folks use the Network framework.

So, it’s fine to use BSD Sockets on iOS — that API is super popular and it’s hard to imagine it going away — but it’s not more ‘native’ than Network framework.

Finally, there are some gotchas associated with using BSD Sockets. See this post for details.

With that out of the way, let’s return to your actual question (-: You wrote:

Is there any way in [BSD Sockets] where we can block the WiFi interface and transfer all traffic through LTE?

BSD Sockets has no direct equivalent to Network frameworks’

prohibitedInterfaceTypes
property. The traditional approach in BSD Sockets is to bind the socket to a specific interface. iOS supports scoped routing, so if a connection is bound to a specific interface it will always run over that interface.

Bind to an interface using

bind
and the interface’s address, but it’s generally easier to use
IP_BOUND_IF
.

Identify the WWAN interface using

getifaddrs
. Specifically, the interface’s interface type will be
IFT_CELLULAR
.

IMPORTANT One thing to watch out for here is that iOS can have multiple WWAN interfaces and there’s no supported way to determine which is the correct one to use for general WWAN traffic. Probably your best option here is to run a test connection using Network framework and then get the interface name from that.

Share and Enjoy

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

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

[1] On iOS. On macOS it currently is, and is likely to remain so until we stop supporting NKEs.

Hi Eskimo,

Thank you for the response.

Yes, we are using BSD socket and we are facing the problem to determine the correct interface to forward WWAN traffic. It seems, there is a limitation of using getifaddrs api.


But replacing the whole library using Network framework api will have impact on project deadline and we need to think about that.


Anyways, thanks for answer.


Best Regards

Arup Sarker

arupcsedu@gmail.com

It seems, there is a limitation of using

getifaddrs
api.

Which limitation exactly?

Share and Enjoy

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

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

Hi Eskimo,

You have told about multiple WWAN interface.


"IMPORTANT One thing to watch out for here is that iOS can have multiple WWAN interfaces and there’s no supported way to determine which is the correct one to use for general WWAN traffic. "


Based on this comment, I have told the about limitation of api.


We are getting all the information of diffrent interface, but we are unable to indentify the cellur one. Please check my below sample code.


#include <stdio.h>
#include <stdlib.h>

/*The following include files for the network interface. */
#include <sys/types.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if_types.h>
/* For "toupper". */
#include <ctype.h>
/* For "strerror". */
#include <string.h>
/* For "errno". */
#include <errno.h>

/*
 * Structure of a Link-Level sockaddr:
 */
struct sockaddr_dl {
  unsigned char sdl_len; /* Total length of sockaddr */
  unsigned char sdl_family; /* AF_LINK */
  unsigned short sdl_index; /* if != 0, system given index for interface */
  unsigned char sdl_type; /* interface type */
  unsigned char sdl_nlen; /* interface name length, no trailing 0 reqd. */
  unsigned char sdl_alen; /* link level address length */
  unsigned char sdl_slen; /* link layer selector length */
  char sdl_data[46]; /* minimum work area, can be larger;
  contains both if name and ll address */
};

  int main() {
  struct ifaddrs *addrs,*tmp;

  getifaddrs(&addrs);
  tmp = addrs;
  struct sockaddr_dl * sdl;

  while (tmp)
  {
       if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_PACKET) {
            sdl = (struct sockaddr_dl *) tmp->ifa_addr;
            printf("%s %d - ", tmp->ifa_name, sdl->sdl_type);
            if (sdl->sdl_type == IFT_CELLULAR) { //IFT_CELLULAR
                 printf("%s is CELLUR adapter", tmp->ifa_name);
            }
            puts("");
       }

       tmp = tmp->ifa_next;
  }

  freeifaddrs(addrs);
}


We are not getting proper informations about the celluar interface.

Can you share the sample or correct in the above code ?

We have used the reference from the below post:

https://stackoverflow.com/questions/56984151/list-ethernet-usb-adapter-interfaces


Another thing, Can you tell me in which scenarios, iOS have multiple WWAN interface?


Best Regards

Arup Sarker

Email : arupcsedu@gmail.com

Can you tell me in which scenarios, iOS have multiple WWAN interface?

I don’t have a comprehensive list but the likely candidates include:

  • Multiple active SIMs

  • Visual Voicemail

  • Personal Hotspot

We are not getting proper informations about the celluar interface.

What do you mean by “proper information”?

Having said that, the code you posted in definitely way off in the weeds. Here’s some code I had lying around to do this:

func wwanInterfaceNames() -> [String] {
    var addrList: UnsafeMutablePointer<ifaddrs>? = nil
    let err = getifaddrs(&addrList)
    guard err == 0, let firstAddr = addrList else { return [] }
    defer {
        freeifaddrs(addrList)
    }
    return sequence(first: firstAddr, next: { $0.pointee.ifa_next })
        .compactMap { addr -> String? in
            guard
                addr.pointee.ifa_addr?.pointee.sa_family == sa_family_t(AF_LINK),
                let name = addr.pointee.ifa_name,
                let data = addr.pointee.ifa_data?.assumingMemoryBound(to: if_data.self),
                data.pointee.ifi_type == IFT_CELLULAR
            else { return nil }
            return String(cString: name)
        }
}

On my iPhone 6 Plus running iOS 13.3 with no SIM installed, it prints:

["pdp_ip0", "pdp_ip1", "pdp_ip4", "pdp_ip3", "pdp_ip2"]

You have told about multiple WWAN interface.

Right. My approach for dealing with this would be to start a test connection using Network framework and then just use the interface it used.

Alternatively, you could start a connection over each WWAN interface — filtering out those without an IP address — and see which one works. This sounds like a pain but you need this code anyway in order to implement happy eyeballs.

Share and Enjoy

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

let myEmail = "eskimo" + "1" + "@apple.com"
Create SIP, RTP, SRTP, RTCP connection with LTE over WiFi
 
 
Q