mirror of
https://github.com/yarrick/iodine.git
synced 2024-12-26 23:03:33 +02:00
Android support (#105) patch from Marcel Bokhorst
This commit is contained in:
parent
66d9428dff
commit
a569030bb7
12 changed files with 142 additions and 27 deletions
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 <winsock2.h>
|
||||
#else
|
||||
#ifdef ANDROID
|
||||
#include "android_dns.h"
|
||||
#endif
|
||||
#include <arpa/nameser.h>
|
||||
#ifdef DARWIN
|
||||
#define BIND_8_COMPAT
|
||||
|
@ -148,6 +151,32 @@ client_get_conn()
|
|||
void
|
||||
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;
|
||||
|
||||
if (inet_aton(cp, &addr) != 1) {
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
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 */
|
||||
#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)
|
||||
{
|
||||
int fd, i;
|
||||
|
@ -276,13 +276,15 @@ check_topdomain(char *str)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WINDOWS32
|
||||
#if defined(WINDOWS32) || defined(ANDROID)
|
||||
#ifndef ANDROID
|
||||
int
|
||||
inet_aton(const char *cp, struct in_addr *inp)
|
||||
{
|
||||
inp->s_addr = inet_addr(cp);
|
||||
return inp->s_addr != INADDR_ANY;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
warn(const char *fmt, ...)
|
||||
|
@ -291,11 +293,13 @@ warn(const char *fmt, ...)
|
|||
|
||||
va_start(list, fmt);
|
||||
if (fmt) fprintf(stderr, fmt, list);
|
||||
#ifndef ANDROID
|
||||
if (errno == 0) {
|
||||
fprintf(stderr, ": WSA error %d\n", WSAGetLastError());
|
||||
} else {
|
||||
fprintf(stderr, ": %s\n", strerror(errno));
|
||||
}
|
||||
#endif
|
||||
va_end(list);
|
||||
}
|
||||
|
||||
|
|
|
@ -119,8 +119,10 @@ void read_password(char*, size_t);
|
|||
|
||||
int check_topdomain(char *);
|
||||
|
||||
#ifdef WINDOWS32
|
||||
#if defined(WINDOWS32) || defined(ANDROID)
|
||||
#ifndef ANDROID
|
||||
int inet_aton(const char *cp, struct in_addr *inp);
|
||||
#endif
|
||||
|
||||
void err(int eval, const char *fmt, ...);
|
||||
void warn(const char *fmt, ...);
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#ifdef WINDOWS32
|
||||
#include "windows.h"
|
||||
#else
|
||||
#ifdef ANDROID
|
||||
#include "android_dns.h"
|
||||
#endif
|
||||
#include <arpa/nameser.h>
|
||||
#ifdef DARWIN
|
||||
#define BIND_8_COMPAT
|
||||
|
|
|
@ -1655,7 +1655,7 @@ tunnel(int tun_fd, int dns_fd, int bind_fd)
|
|||
requests during heavy upstream traffic.
|
||||
20msec: ~8 packs every 1/50sec = ~400 DNSreq/sec,
|
||||
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 &&
|
||||
users[userid].last_pkt + 60 > time(NULL)) {
|
||||
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 */
|
||||
for (userid = 0; userid < USERS; userid++)
|
||||
for (userid = 0; userid < created_users; userid++)
|
||||
if (users[userid].active && !users[userid].disabled &&
|
||||
users[userid].last_pkt + 60 > time(NULL) &&
|
||||
users[userid].q_sendrealsoon.id != 0 &&
|
||||
|
|
12
src/tun.c
12
src/tun.c
|
@ -24,6 +24,10 @@
|
|||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifndef IFCONFIGPATH
|
||||
#define IFCONFIGPATH "/sbin/"
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS32
|
||||
#include <winsock2.h>
|
||||
#include <winioctl.h>
|
||||
|
@ -71,7 +75,11 @@ open_tun(const char *tun_device)
|
|||
int i;
|
||||
int tun_fd;
|
||||
struct ifreq ifreq;
|
||||
#ifdef ANDROID
|
||||
char *tunnel = "/dev/tun";
|
||||
#else
|
||||
char *tunnel = "/dev/net/tun";
|
||||
#endif
|
||||
|
||||
if ((tun_fd = open(tunnel, O_RDWR)) < 0) {
|
||||
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
|
||||
snprintf(cmdline, sizeof(cmdline),
|
||||
"/sbin/ifconfig %s %s %s netmask %s",
|
||||
IFCONFIGPATH "ifconfig %s %s %s netmask %s",
|
||||
if_name,
|
||||
ip,
|
||||
#ifdef FREEBSD
|
||||
|
@ -522,7 +530,7 @@ tun_setmtu(const unsigned mtu)
|
|||
|
||||
if (mtu > 200 && mtu <= 1500) {
|
||||
snprintf(cmdline, sizeof(cmdline),
|
||||
"/sbin/ifconfig %s mtu %u",
|
||||
IFCONFIGPATH "ifconfig %s mtu %u",
|
||||
if_name,
|
||||
mtu);
|
||||
|
||||
|
|
30
src/user.c
30
src/user.c
|
@ -33,7 +33,8 @@
|
|||
#include "encoding.h"
|
||||
#include "user.h"
|
||||
|
||||
struct user users[USERS];
|
||||
struct user *users;
|
||||
unsigned usercount;
|
||||
|
||||
int
|
||||
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 skip = 0;
|
||||
char newip[16];
|
||||
int created_users = 0;
|
||||
|
||||
int maxusers;
|
||||
|
||||
|
@ -57,9 +57,10 @@ init_users(in_addr_t my_ip, int netbits)
|
|||
ipstart.s_addr = my_ip & net.s_addr;
|
||||
|
||||
maxusers = (1 << (32-netbits)) - 3; /* 3: Net addr, broadcast addr, iodined addr */
|
||||
usercount = MIN(maxusers, USERS);
|
||||
|
||||
memset(users, 0, USERS * sizeof(struct user));
|
||||
for (i = 0; i < USERS; i++) {
|
||||
users = calloc(usercount, sizeof(struct user));
|
||||
for (i = 0; i < usercount; i++) {
|
||||
in_addr_t ip;
|
||||
users[i].id = i;
|
||||
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;
|
||||
net.s_addr = ip;
|
||||
if (maxusers-- < 1) {
|
||||
users[i].disabled = 1;
|
||||
} else {
|
||||
users[i].disabled = 0;
|
||||
created_users++;
|
||||
}
|
||||
users[i].disabled = 0;
|
||||
users[i].active = 0;
|
||||
/* Rest is reset on login ('V' packet) */
|
||||
}
|
||||
|
||||
return created_users;
|
||||
return usercount;
|
||||
}
|
||||
|
||||
const char*
|
||||
|
@ -100,7 +96,7 @@ users_waiting_on_reply()
|
|||
int i;
|
||||
|
||||
ret = 0;
|
||||
for (i = 0; i < USERS; i++) {
|
||||
for (i = 0; i < usercount; i++) {
|
||||
if (users[i].active && !users[i].disabled &&
|
||||
users[i].last_pkt + 60 > time(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;
|
||||
|
||||
ret = -1;
|
||||
for (i = 0; i < USERS; i++) {
|
||||
for (i = 0; i < usercount; i++) {
|
||||
if (users[i].active && !users[i].disabled &&
|
||||
users[i].last_pkt + 60 > time(NULL) &&
|
||||
ip == users[i].tun_ip) {
|
||||
|
@ -143,7 +139,7 @@ all_users_waiting_to_send()
|
|||
|
||||
ret = 1;
|
||||
now = time(NULL);
|
||||
for (i = 0; i < USERS; i++) {
|
||||
for (i = 0; i < usercount; i++) {
|
||||
if (users[i].active && !users[i].disabled &&
|
||||
users[i].last_pkt + 60 > now &&
|
||||
((users[i].conn == CONN_RAW_UDP) ||
|
||||
|
@ -167,7 +163,7 @@ find_available_user()
|
|||
{
|
||||
int ret = -1;
|
||||
int i;
|
||||
for (i = 0; i < USERS; i++) {
|
||||
for (i = 0; i < usercount; i++) {
|
||||
/* Not used at all or not used in one minute */
|
||||
if ((!users[i].active || users[i].last_pkt + 60 < time(NULL)) && !users[i].disabled) {
|
||||
users[i].active = 1;
|
||||
|
@ -184,7 +180,7 @@ find_available_user()
|
|||
void
|
||||
user_switch_codec(int userid, struct encoder *enc)
|
||||
{
|
||||
if (userid < 0 || userid >= USERS)
|
||||
if (userid < 0 || userid >= usercount)
|
||||
return;
|
||||
|
||||
users[userid].encoder = enc;
|
||||
|
@ -193,7 +189,7 @@ user_switch_codec(int userid, struct encoder *enc)
|
|||
void
|
||||
user_set_conn_type(int userid, enum connection c)
|
||||
{
|
||||
if (userid < 0 || userid >= USERS)
|
||||
if (userid < 0 || userid >= usercount)
|
||||
return;
|
||||
|
||||
if (c < 0 || c >= CONN_MAX)
|
||||
|
|
|
@ -73,7 +73,7 @@ struct user {
|
|||
#endif
|
||||
};
|
||||
|
||||
extern struct user users[USERS];
|
||||
extern struct user *users;
|
||||
|
||||
int init_users(in_addr_t, int);
|
||||
const char* users_get_first_ip();
|
||||
|
|
11
src/util.c
11
src/util.c
|
@ -25,6 +25,16 @@ get_resolvconf_addr()
|
|||
#ifndef WINDOWS32
|
||||
char buf[80];
|
||||
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;
|
||||
|
||||
|
@ -41,6 +51,7 @@ get_resolvconf_addr()
|
|||
}
|
||||
|
||||
fclose(fp);
|
||||
#endif
|
||||
#else /* !WINDOWS32 */
|
||||
FIXED_INFO *fixed_info;
|
||||
ULONG buflen;
|
||||
|
|
|
@ -32,10 +32,11 @@ START_TEST(test_init_users)
|
|||
in_addr_t ip;
|
||||
char givenip[16];
|
||||
int i;
|
||||
int count;
|
||||
|
||||
ip = inet_addr("127.0.0.1");
|
||||
init_users(ip, 27);
|
||||
for (i = 0; i < USERS; i++) {
|
||||
count = init_users(ip, 27);
|
||||
for (i = 0; i < count; i++) {
|
||||
fail_unless(users[i].id == i);
|
||||
fail_unless(users[i].q.id == 0);
|
||||
fail_unless(users[i].inpacket.len == 0);
|
||||
|
|
Loading…
Reference in a new issue