-
-
Save avesus/fdb465b60a4f5204845c to your computer and use it in GitHub Desktop.
# include <sys/types.h> | |
# include <sys/socket.h> | |
# include <ifaddrs.h> | |
# include <arpa/inet.h> | |
# include <netinet/in.h> | |
// Bad dirty quick functions written by hot fingers: | |
char* ipToStr(sockaddr* addr) { | |
static char ip[32]; | |
sprintf(ip, "%d.%d.%d.%d", (unsigned char)addr->sa_data[2], (unsigned char)addr->sa_data[3], (unsigned char)addr->sa_data[4], (unsigned char)addr->sa_data[5]); | |
return ip; | |
} | |
// so on... | |
char* ip32ToStr(int addr) { | |
static char ip[32]; | |
char* bytes = (char*)&addr; | |
sprintf(ip, "%d.%d.%d.%d", (unsigned char)bytes[3], (unsigned char)bytes[2], (unsigned char)bytes[1], (unsigned char)bytes[0]); | |
return ip; | |
} | |
// Look here: | |
void test_stun_ip_multipath_ios() { | |
ifaddrs* addrs = 0; | |
getifaddrs(&addrs); | |
sockaddr* clt1 = 0; | |
sockaddr* clt2 = 0; | |
while(addrs) { | |
char* ip = ipToStr(addrs->ifa_addr); | |
fprintf(stderr, "%s: %s\n", addrs->ifa_name, ip); | |
// FIX THIS ACCORDING YOUR ACTUAL Wi-Fi and 3G IP Addresses: | |
if (0 == strncmp("192.168.", ip, 8) ) { | |
clt1 = addrs->ifa_addr; | |
} else if (0 == strncmp("10.", ip, 3) ) { | |
clt2 = addrs->ifa_addr; | |
} | |
addrs = addrs->ifa_next; | |
} | |
int sock1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | |
int sock2 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | |
sockaddr_in cltAddr = {0}; | |
cltAddr.sin_family = AF_INET; | |
cltAddr.sin_port = htons(5555); | |
// This binds to the enumerated addresses. | |
// Auto-assigned ports could be acquired by getsockname, i.e., | |
// int nLen = sizeof(serverAddr); | |
// getsockname(sock, (sockaddr*)&serverAddr, &nLen); | |
// int recvOnPort = ntohs(serverAddr.sin_port); | |
// printf("My port: %d\n", recvOnPort); | |
int res1 = bind(sock1, (struct sockaddr *)clt1, sizeof(sockaddr_in)); | |
int res2 = bind(sock2, (struct sockaddr *)clt2, sizeof(sockaddr_in)); | |
sockaddr_in serverAddr = {0}; | |
serverAddr.sin_family = AF_INET; | |
// A STUN server (I forgot whom) | |
serverAddr.sin_addr.s_addr = inet_addr("23.21.150.121"); | |
serverAddr.sin_port = htons(3478); | |
struct StunRequest | |
{ | |
uint16_t msgType; | |
uint16_t payloadLen; | |
uint32_t magic; | |
uint8_t transaction[12]; | |
}; | |
StunRequest r = {0}; | |
r.msgType = 0x0100; | |
r.payloadLen = 0; | |
r.magic = 0x42A41221; | |
r.transaction[0] = 5; | |
r.transaction[5] = 7; | |
// Send thru ONE SOCKET | |
int sentBytes = sendto(sock1, (char*)&r, sizeof(r), 0, | |
(sockaddr*)&serverAddr, sizeof(serverAddr)); | |
// Send thru ANOTHER SOCKET | |
int sentBytes2 = sendto(sock2, (char*)&r, sizeof(r), 0, | |
(sockaddr*)&serverAddr, sizeof(serverAddr)); | |
char recvBuffer[ 1280 ] = {0}; | |
sockaddr_in from = {0}; | |
socklen_t fromLen = sizeof(from); | |
ssize_t nrecvd = recvfrom(sock1, (void*)recvBuffer, sizeof(recvBuffer), | |
0, (sockaddr*)&from, &fromLen); | |
uint16_t externalPort = ntohs(*((uint16_t*)&recvBuffer[26]));// ^ 0x2112; | |
uint32_t externalIp = ntohl(*((uint32_t*)&recvBuffer[28]));// ^ 0x2112A442; | |
char* extIp1 = ip32ToStr(externalIp); | |
fprintf(stderr, "External IP1: %s", extIp1); | |
nrecvd = recvfrom(sock2, (void*)recvBuffer, sizeof(recvBuffer), | |
0, (sockaddr*)&from, &fromLen); | |
externalPort = ntohs(*((uint16_t*)&recvBuffer[26]));// ^ 0x2112; | |
externalIp = ntohl(*((uint32_t*)&recvBuffer[28]));// ^ 0x2112A442; | |
char* extIp2 = ip32ToStr(externalIp); | |
fprintf(stderr, "External IP2: %s", extIp2); | |
} |
Hi @avesus,
I need to make HTTP request on 2G/3g/4g only in iOS. In android its possible using connectivityManager trying to do the same in iOS but no luck.
If device is connected to Wifi and mobile data both, I need to check and make HTTP request over mobile network.
I know it is not possible to do with the high level API's. But with low-level APIs I can force a particular TCP connection to run over a particular interface, which allows this sort of thing.
Please provide a recommended solution for the same.
Regards,
Bhawna
Please, enumerate interfaces, obtain the last IP addresses, and re-bind sockets.
Hi, @avesus
I have used above code to make use of wifi and cellular interfaces in parallel.
But it don't work in Network Extensions(Packet Tunnel). I receive errno 49.
Please provide a recommended solution for me, Thanks!
Regards,
Kevinhao
@haojingjing2018 Did you got any solution? I am facing the same problem right now.
Hi @shivintu ,
Hope you have read the comment
// FIX THIS ACCORDING YOUR ACTUAL Wi-Fi and 3G IP Addresses
carefully: you need two different IP addresses. Never bind to 0.0.0.0.
Which version of iOS you have used?