-
-
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 @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?
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,
I have used above code to make use of wifi and cellular interfaces in parallel. The thing is even I switched off wifi and try to send data using cellular interface the two sendto(sock1, ....) sendto(sock2, ....) uses cellular interfaces why the sock1 didn't throw error as it is wifi and its off to send the data?