mirror of
https://github.com/yarrick/iodine.git
synced 2024-11-22 06:41:26 +00:00
Android support (#105) patch from Marcel Bokhorst
This commit is contained in:
parent
66d9428dff
commit
a569030bb7
22
src/Android.mk
Normal file
22
src/Android.mk
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#
|
||||||
|
# iodine for Android
|
||||||
|
#
|
||||||
|
# by Marcel Bokhorst
|
||||||
|
# http://blog.bokhorst.biz/5123/computers-en-internet/iodine-for-android/
|
||||||
|
#
|
||||||
|
# cd iodine-0.6.0-rc1/src
|
||||||
|
# make base64u.h base64u.c
|
||||||
|
# .../ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk
|
||||||
|
#
|
||||||
|
|
||||||
|
LOCAL_PATH:= $(call my-dir)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := iodine
|
||||||
|
LOCAL_SRC_FILES := tun.c dns.c read.c encoding.c login.c base32.c base64.c base64u.c base128.c md5.c common.c iodine.c client.c util.c
|
||||||
|
LOCAL_CFLAGS := -c -DANDROID -DLINUX -DIFCONFIGPATH=\"/system/bin/\" -Wall
|
||||||
|
LOCAL_LDLIBS := -lz
|
||||||
|
|
||||||
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|
39
src/android_dns.h
Normal file
39
src/android_dns.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
#ifndef __FIX_ANDROID_H__
|
||||||
|
#define __FIX_ANDROID_H__
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned id :16;
|
||||||
|
unsigned rd :1;
|
||||||
|
unsigned tc :1;
|
||||||
|
unsigned aa :1;
|
||||||
|
unsigned opcode :4;
|
||||||
|
unsigned qr :1;
|
||||||
|
unsigned rcode :4;
|
||||||
|
unsigned cd: 1;
|
||||||
|
unsigned ad: 1;
|
||||||
|
unsigned unused :1;
|
||||||
|
unsigned ra :1;
|
||||||
|
unsigned qdcount :16;
|
||||||
|
unsigned ancount :16;
|
||||||
|
unsigned nscount :16;
|
||||||
|
unsigned arcount :16;
|
||||||
|
} HEADER;
|
||||||
|
|
||||||
|
#define NOERROR 0
|
||||||
|
#define FORMERR 1
|
||||||
|
#define SERVFAIL 2
|
||||||
|
#define NXDOMAIN 3
|
||||||
|
#define NOTIMP 4
|
||||||
|
#define REFUSED 5
|
||||||
|
|
||||||
|
#define C_IN 1
|
||||||
|
|
||||||
|
#define T_A 1
|
||||||
|
#define T_CNAME 5
|
||||||
|
#define T_NULL 10
|
||||||
|
#define T_MX 15
|
||||||
|
#define T_TXT 16
|
||||||
|
#define T_SRV 33
|
||||||
|
|
||||||
|
#endif
|
29
src/client.c
29
src/client.c
|
@ -31,6 +31,9 @@
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#else
|
#else
|
||||||
|
#ifdef ANDROID
|
||||||
|
#include "android_dns.h"
|
||||||
|
#endif
|
||||||
#include <arpa/nameser.h>
|
#include <arpa/nameser.h>
|
||||||
#ifdef DARWIN
|
#ifdef DARWIN
|
||||||
#define BIND_8_COMPAT
|
#define BIND_8_COMPAT
|
||||||
|
@ -148,6 +151,32 @@ client_get_conn()
|
||||||
void
|
void
|
||||||
client_set_nameserver(const char *cp, int port)
|
client_set_nameserver(const char *cp, int port)
|
||||||
{
|
{
|
||||||
|
#ifdef ANDROID
|
||||||
|
struct addrinfo hints, *result, *p;
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = AF_INET;
|
||||||
|
|
||||||
|
char sport[10];
|
||||||
|
sprintf(sport, "%d", port);
|
||||||
|
|
||||||
|
getaddrinfo(cp, sport, &hints, &result);
|
||||||
|
if (result == NULL)
|
||||||
|
errx(1, "Cannot resolve %s:%s (no network?)", cp, sport);
|
||||||
|
else {
|
||||||
|
for (p = result;p != NULL; p = p->ai_next) {
|
||||||
|
if (p->ai_family == AF_INET) { /* IPv4 */
|
||||||
|
struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
|
||||||
|
memset(&nameserv, 0, sizeof(nameserv));
|
||||||
|
nameserv.sin_family = AF_INET;
|
||||||
|
nameserv.sin_port = htons(port);
|
||||||
|
nameserv.sin_addr = ipv4->sin_addr;
|
||||||
|
freeaddrinfo(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
freeaddrinfo(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
|
|
||||||
if (inet_aton(cp, &addr) != 1) {
|
if (inet_aton(cp, &addr) != 1) {
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
const unsigned char raw_header[RAW_HDR_LEN] = { 0x10, 0xd1, 0x9e, 0x00 };
|
const unsigned char raw_header[RAW_HDR_LEN] = { 0x10, 0xd1, 0x9e, 0x00 };
|
||||||
|
|
||||||
/* daemon(3) exists only in 4.4BSD or later, and in GNU libc */
|
/* daemon(3) exists only in 4.4BSD or later, and in GNU libc */
|
||||||
#if !defined(WINDOWS32) && !(defined(BSD) && (BSD >= 199306)) && !defined(__GLIBC__)
|
#if !defined(ANDROID) && !defined(WINDOWS32) && !(defined(BSD) && (BSD >= 199306)) && !defined(__GLIBC__)
|
||||||
static int daemon(int nochdir, int noclose)
|
static int daemon(int nochdir, int noclose)
|
||||||
{
|
{
|
||||||
int fd, i;
|
int fd, i;
|
||||||
|
@ -276,13 +276,15 @@ check_topdomain(char *str)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WINDOWS32
|
#if defined(WINDOWS32) || defined(ANDROID)
|
||||||
|
#ifndef ANDROID
|
||||||
int
|
int
|
||||||
inet_aton(const char *cp, struct in_addr *inp)
|
inet_aton(const char *cp, struct in_addr *inp)
|
||||||
{
|
{
|
||||||
inp->s_addr = inet_addr(cp);
|
inp->s_addr = inet_addr(cp);
|
||||||
return inp->s_addr != INADDR_ANY;
|
return inp->s_addr != INADDR_ANY;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
warn(const char *fmt, ...)
|
warn(const char *fmt, ...)
|
||||||
|
@ -291,11 +293,13 @@ warn(const char *fmt, ...)
|
||||||
|
|
||||||
va_start(list, fmt);
|
va_start(list, fmt);
|
||||||
if (fmt) fprintf(stderr, fmt, list);
|
if (fmt) fprintf(stderr, fmt, list);
|
||||||
|
#ifndef ANDROID
|
||||||
if (errno == 0) {
|
if (errno == 0) {
|
||||||
fprintf(stderr, ": WSA error %d\n", WSAGetLastError());
|
fprintf(stderr, ": WSA error %d\n", WSAGetLastError());
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, ": %s\n", strerror(errno));
|
fprintf(stderr, ": %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
va_end(list);
|
va_end(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,8 +119,10 @@ void read_password(char*, size_t);
|
||||||
|
|
||||||
int check_topdomain(char *);
|
int check_topdomain(char *);
|
||||||
|
|
||||||
#ifdef WINDOWS32
|
#if defined(WINDOWS32) || defined(ANDROID)
|
||||||
|
#ifndef ANDROID
|
||||||
int inet_aton(const char *cp, struct in_addr *inp);
|
int inet_aton(const char *cp, struct in_addr *inp);
|
||||||
|
#endif
|
||||||
|
|
||||||
void err(int eval, const char *fmt, ...);
|
void err(int eval, const char *fmt, ...);
|
||||||
void warn(const char *fmt, ...);
|
void warn(const char *fmt, ...);
|
||||||
|
|
|
@ -25,6 +25,9 @@
|
||||||
#ifdef WINDOWS32
|
#ifdef WINDOWS32
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#else
|
#else
|
||||||
|
#ifdef ANDROID
|
||||||
|
#include "android_dns.h"
|
||||||
|
#endif
|
||||||
#include <arpa/nameser.h>
|
#include <arpa/nameser.h>
|
||||||
#ifdef DARWIN
|
#ifdef DARWIN
|
||||||
#define BIND_8_COMPAT
|
#define BIND_8_COMPAT
|
||||||
|
|
|
@ -1655,7 +1655,7 @@ tunnel(int tun_fd, int dns_fd, int bind_fd)
|
||||||
requests during heavy upstream traffic.
|
requests during heavy upstream traffic.
|
||||||
20msec: ~8 packs every 1/50sec = ~400 DNSreq/sec,
|
20msec: ~8 packs every 1/50sec = ~400 DNSreq/sec,
|
||||||
or ~1200bytes every 1/50sec = ~0.5 Mbit/sec upstream */
|
or ~1200bytes every 1/50sec = ~0.5 Mbit/sec upstream */
|
||||||
for (userid = 0; userid < USERS; userid++) {
|
for (userid = 0; userid < created_users; userid++) {
|
||||||
if (users[userid].active && !users[userid].disabled &&
|
if (users[userid].active && !users[userid].disabled &&
|
||||||
users[userid].last_pkt + 60 > time(NULL)) {
|
users[userid].last_pkt + 60 > time(NULL)) {
|
||||||
users[userid].q_sendrealsoon_new = 0;
|
users[userid].q_sendrealsoon_new = 0;
|
||||||
|
@ -1707,7 +1707,7 @@ tunnel(int tun_fd, int dns_fd, int bind_fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send realsoon's if tun or dns didn't already */
|
/* Send realsoon's if tun or dns didn't already */
|
||||||
for (userid = 0; userid < USERS; userid++)
|
for (userid = 0; userid < created_users; userid++)
|
||||||
if (users[userid].active && !users[userid].disabled &&
|
if (users[userid].active && !users[userid].disabled &&
|
||||||
users[userid].last_pkt + 60 > time(NULL) &&
|
users[userid].last_pkt + 60 > time(NULL) &&
|
||||||
users[userid].q_sendrealsoon.id != 0 &&
|
users[userid].q_sendrealsoon.id != 0 &&
|
||||||
|
|
12
src/tun.c
12
src/tun.c
|
@ -24,6 +24,10 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#ifndef IFCONFIGPATH
|
||||||
|
#define IFCONFIGPATH "/sbin/"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WINDOWS32
|
#ifdef WINDOWS32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <winioctl.h>
|
#include <winioctl.h>
|
||||||
|
@ -71,7 +75,11 @@ open_tun(const char *tun_device)
|
||||||
int i;
|
int i;
|
||||||
int tun_fd;
|
int tun_fd;
|
||||||
struct ifreq ifreq;
|
struct ifreq ifreq;
|
||||||
|
#ifdef ANDROID
|
||||||
|
char *tunnel = "/dev/tun";
|
||||||
|
#else
|
||||||
char *tunnel = "/dev/net/tun";
|
char *tunnel = "/dev/net/tun";
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((tun_fd = open(tunnel, O_RDWR)) < 0) {
|
if ((tun_fd = open(tunnel, O_RDWR)) < 0) {
|
||||||
warn("open_tun: %s: %s", tunnel, strerror(errno));
|
warn("open_tun: %s: %s", tunnel, strerror(errno));
|
||||||
|
@ -455,7 +463,7 @@ tun_setip(const char *ip, const char *other_ip, int netbits)
|
||||||
}
|
}
|
||||||
#ifndef WINDOWS32
|
#ifndef WINDOWS32
|
||||||
snprintf(cmdline, sizeof(cmdline),
|
snprintf(cmdline, sizeof(cmdline),
|
||||||
"/sbin/ifconfig %s %s %s netmask %s",
|
IFCONFIGPATH "ifconfig %s %s %s netmask %s",
|
||||||
if_name,
|
if_name,
|
||||||
ip,
|
ip,
|
||||||
#ifdef FREEBSD
|
#ifdef FREEBSD
|
||||||
|
@ -522,7 +530,7 @@ tun_setmtu(const unsigned mtu)
|
||||||
|
|
||||||
if (mtu > 200 && mtu <= 1500) {
|
if (mtu > 200 && mtu <= 1500) {
|
||||||
snprintf(cmdline, sizeof(cmdline),
|
snprintf(cmdline, sizeof(cmdline),
|
||||||
"/sbin/ifconfig %s mtu %u",
|
IFCONFIGPATH "ifconfig %s mtu %u",
|
||||||
if_name,
|
if_name,
|
||||||
mtu);
|
mtu);
|
||||||
|
|
||||||
|
|
28
src/user.c
28
src/user.c
|
@ -33,7 +33,8 @@
|
||||||
#include "encoding.h"
|
#include "encoding.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
|
||||||
struct user users[USERS];
|
struct user *users;
|
||||||
|
unsigned usercount;
|
||||||
|
|
||||||
int
|
int
|
||||||
init_users(in_addr_t my_ip, int netbits)
|
init_users(in_addr_t my_ip, int netbits)
|
||||||
|
@ -41,7 +42,6 @@ init_users(in_addr_t my_ip, int netbits)
|
||||||
int i;
|
int i;
|
||||||
int skip = 0;
|
int skip = 0;
|
||||||
char newip[16];
|
char newip[16];
|
||||||
int created_users = 0;
|
|
||||||
|
|
||||||
int maxusers;
|
int maxusers;
|
||||||
|
|
||||||
|
@ -57,9 +57,10 @@ init_users(in_addr_t my_ip, int netbits)
|
||||||
ipstart.s_addr = my_ip & net.s_addr;
|
ipstart.s_addr = my_ip & net.s_addr;
|
||||||
|
|
||||||
maxusers = (1 << (32-netbits)) - 3; /* 3: Net addr, broadcast addr, iodined addr */
|
maxusers = (1 << (32-netbits)) - 3; /* 3: Net addr, broadcast addr, iodined addr */
|
||||||
|
usercount = MIN(maxusers, USERS);
|
||||||
|
|
||||||
memset(users, 0, USERS * sizeof(struct user));
|
users = calloc(usercount, sizeof(struct user));
|
||||||
for (i = 0; i < USERS; i++) {
|
for (i = 0; i < usercount; i++) {
|
||||||
in_addr_t ip;
|
in_addr_t ip;
|
||||||
users[i].id = i;
|
users[i].id = i;
|
||||||
snprintf(newip, sizeof(newip), "0.0.0.%d", i + skip + 1);
|
snprintf(newip, sizeof(newip), "0.0.0.%d", i + skip + 1);
|
||||||
|
@ -72,17 +73,12 @@ init_users(in_addr_t my_ip, int netbits)
|
||||||
}
|
}
|
||||||
users[i].tun_ip = ip;
|
users[i].tun_ip = ip;
|
||||||
net.s_addr = ip;
|
net.s_addr = ip;
|
||||||
if (maxusers-- < 1) {
|
|
||||||
users[i].disabled = 1;
|
|
||||||
} else {
|
|
||||||
users[i].disabled = 0;
|
users[i].disabled = 0;
|
||||||
created_users++;
|
|
||||||
}
|
|
||||||
users[i].active = 0;
|
users[i].active = 0;
|
||||||
/* Rest is reset on login ('V' packet) */
|
/* Rest is reset on login ('V' packet) */
|
||||||
}
|
}
|
||||||
|
|
||||||
return created_users;
|
return usercount;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
|
@ -100,7 +96,7 @@ users_waiting_on_reply()
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
for (i = 0; i < USERS; i++) {
|
for (i = 0; i < usercount; i++) {
|
||||||
if (users[i].active && !users[i].disabled &&
|
if (users[i].active && !users[i].disabled &&
|
||||||
users[i].last_pkt + 60 > time(NULL) &&
|
users[i].last_pkt + 60 > time(NULL) &&
|
||||||
users[i].q.id != 0 && users[i].conn == CONN_DNS_NULL) {
|
users[i].q.id != 0 && users[i].conn == CONN_DNS_NULL) {
|
||||||
|
@ -118,7 +114,7 @@ find_user_by_ip(uint32_t ip)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ret = -1;
|
ret = -1;
|
||||||
for (i = 0; i < USERS; i++) {
|
for (i = 0; i < usercount; i++) {
|
||||||
if (users[i].active && !users[i].disabled &&
|
if (users[i].active && !users[i].disabled &&
|
||||||
users[i].last_pkt + 60 > time(NULL) &&
|
users[i].last_pkt + 60 > time(NULL) &&
|
||||||
ip == users[i].tun_ip) {
|
ip == users[i].tun_ip) {
|
||||||
|
@ -143,7 +139,7 @@ all_users_waiting_to_send()
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
for (i = 0; i < USERS; i++) {
|
for (i = 0; i < usercount; i++) {
|
||||||
if (users[i].active && !users[i].disabled &&
|
if (users[i].active && !users[i].disabled &&
|
||||||
users[i].last_pkt + 60 > now &&
|
users[i].last_pkt + 60 > now &&
|
||||||
((users[i].conn == CONN_RAW_UDP) ||
|
((users[i].conn == CONN_RAW_UDP) ||
|
||||||
|
@ -167,7 +163,7 @@ find_available_user()
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < USERS; i++) {
|
for (i = 0; i < usercount; i++) {
|
||||||
/* Not used at all or not used in one minute */
|
/* Not used at all or not used in one minute */
|
||||||
if ((!users[i].active || users[i].last_pkt + 60 < time(NULL)) && !users[i].disabled) {
|
if ((!users[i].active || users[i].last_pkt + 60 < time(NULL)) && !users[i].disabled) {
|
||||||
users[i].active = 1;
|
users[i].active = 1;
|
||||||
|
@ -184,7 +180,7 @@ find_available_user()
|
||||||
void
|
void
|
||||||
user_switch_codec(int userid, struct encoder *enc)
|
user_switch_codec(int userid, struct encoder *enc)
|
||||||
{
|
{
|
||||||
if (userid < 0 || userid >= USERS)
|
if (userid < 0 || userid >= usercount)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
users[userid].encoder = enc;
|
users[userid].encoder = enc;
|
||||||
|
@ -193,7 +189,7 @@ user_switch_codec(int userid, struct encoder *enc)
|
||||||
void
|
void
|
||||||
user_set_conn_type(int userid, enum connection c)
|
user_set_conn_type(int userid, enum connection c)
|
||||||
{
|
{
|
||||||
if (userid < 0 || userid >= USERS)
|
if (userid < 0 || userid >= usercount)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (c < 0 || c >= CONN_MAX)
|
if (c < 0 || c >= CONN_MAX)
|
||||||
|
|
|
@ -73,7 +73,7 @@ struct user {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct user users[USERS];
|
extern struct user *users;
|
||||||
|
|
||||||
int init_users(in_addr_t, int);
|
int init_users(in_addr_t, int);
|
||||||
const char* users_get_first_ip();
|
const char* users_get_first_ip();
|
||||||
|
|
11
src/util.c
11
src/util.c
|
@ -25,6 +25,16 @@ get_resolvconf_addr()
|
||||||
#ifndef WINDOWS32
|
#ifndef WINDOWS32
|
||||||
char buf[80];
|
char buf[80];
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
#ifdef ANDROID
|
||||||
|
fp = popen("getprop net.dns1", "r");
|
||||||
|
if (fp == NULL)
|
||||||
|
err(1, "getprop net.dns1 failed");
|
||||||
|
if (fgets(buf, sizeof(buf), fp) == NULL)
|
||||||
|
err(1, "read getprop net.dns1 failed");
|
||||||
|
if (sscanf(buf, "%15s", addr) == 1)
|
||||||
|
rv = addr;
|
||||||
|
pclose(fp);
|
||||||
|
#else
|
||||||
|
|
||||||
rv = NULL;
|
rv = NULL;
|
||||||
|
|
||||||
|
@ -41,6 +51,7 @@ get_resolvconf_addr()
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
#endif
|
||||||
#else /* !WINDOWS32 */
|
#else /* !WINDOWS32 */
|
||||||
FIXED_INFO *fixed_info;
|
FIXED_INFO *fixed_info;
|
||||||
ULONG buflen;
|
ULONG buflen;
|
||||||
|
|
|
@ -32,10 +32,11 @@ START_TEST(test_init_users)
|
||||||
in_addr_t ip;
|
in_addr_t ip;
|
||||||
char givenip[16];
|
char givenip[16];
|
||||||
int i;
|
int i;
|
||||||
|
int count;
|
||||||
|
|
||||||
ip = inet_addr("127.0.0.1");
|
ip = inet_addr("127.0.0.1");
|
||||||
init_users(ip, 27);
|
count = init_users(ip, 27);
|
||||||
for (i = 0; i < USERS; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
fail_unless(users[i].id == i);
|
fail_unless(users[i].id == i);
|
||||||
fail_unless(users[i].q.id == 0);
|
fail_unless(users[i].q.id == 0);
|
||||||
fail_unless(users[i].inpacket.len == 0);
|
fail_unless(users[i].inpacket.len == 0);
|
||||||
|
|
Loading…
Reference in a new issue