Skip to content

Instantly share code, notes, and snippets.

@avesus
Created April 21, 2015 22:30
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save avesus/fdb465b60a4f5204845c to your computer and use it in GitHub Desktop.
Save avesus/fdb465b60a4f5204845c to your computer and use it in GitHub Desktop.
iOS Multipath BSD Sockets Test. Comments welcomed!
# 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);
}
@haojingjing2018
Copy link

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

@RahulRai02
Copy link

@haojingjing2018 Did you got any solution? I am facing the same problem right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment