Skip to content

Commit

Permalink
Merge branch 'release/0.5.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
lparam committed Aug 30, 2017
2 parents eaf61e8 + 077b5ca commit e922add
Show file tree
Hide file tree
Showing 21 changed files with 267 additions and 114 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@

*.swp
.ycm_extra_conf.pyc
.vscode
/core
/xTun
/xTund
2 changes: 1 addition & 1 deletion 3rd/libsodium
Submodule libsodium updated 425 files
2 changes: 1 addition & 1 deletion 3rd/libuv
Submodule libuv updated 226 files
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
v0.5.2 (2017-8-30)
-----------
* Feature: NAT Keepalive


v0.5.1 (2016-7-23)
-----------
* Fix: Free buffer
Expand Down
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MAJOR = 0
MINOR = 5
PATCH = 1
PATCH = 2
NAME = xTun

ifdef O
Expand Down Expand Up @@ -120,6 +120,7 @@ libsodium: $(OBJTREE)/3rd/libsodium/Makefile

$(XTUN): \
$(OBJTREE)/src/util.o \
$(OBJTREE)/src/common.o \
$(OBJTREE)/src/logger.o \
$(OBJTREE)/src/daemon.o \
$(OBJTREE)/src/signal.o \
Expand All @@ -136,6 +137,7 @@ $(XTUN): \

$(XTUN_STATIC): \
$(OBJTREE)/src/util.o \
$(OBJTREE)/src/common.o \
$(OBJTREE)/src/logger.o \
$(OBJTREE)/src/crypto.o \
$(OBJTREE)/src/checksum.o \
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ Features
* Stateless
* CCA security
* Low cost (CPU, RAM and packet overhead)
* Cross-platform, including PC (Linux, Mobile ([Android](https://github.com/lparam/xTun-android)) and Router (OpenWRT)
* Cross-platform, including PC (Linux), Mobile ([Android](https://github.com/lparam/xTun-android)) and Router (OpenWRT)
* TCP and UDP support
* Parallelization


Expand Down
2 changes: 1 addition & 1 deletion openwrt/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk

PKG_NAME:=xTun
PKG_VERSION:=0.5.1
PKG_VERSION:=0.5.2
PKG_RELEASE=

PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
Expand Down
3 changes: 1 addition & 2 deletions openwrt/files/xTun.init
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ PORT=PORt
PASSWORD=PASSWORD

IP_ROUTE_TABLE=xTun
FWMARK="0x02/0x02"
FWMARK="0x023/0x023"
SETNAME=wall
CHAIN=xTun
DNS=8.8.8.8
Expand Down Expand Up @@ -71,7 +71,6 @@ net_start() {
iptables -t mangle -A PREROUTING -j $CHAIN
iptables -t mangle -A OUTPUT -j $CHAIN

ip route del default dev $IFACE table $IP_ROUTE_TABLE > /dev/null 2>&1
xTun_rule_ids=`ip rule list | grep "lookup $IP_ROUTE_TABLE" | sed 's/://g' | awk '{print $1}'`
for rule_id in $xTun_rule_ids
do
Expand Down
7 changes: 4 additions & 3 deletions src/android.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
#include <netinet/udp.h>

#include "uv.h"

#include "logger.h"
#include "util.h"
#include "android.h"
#include "checksum.h"
#include "dns.h"
#include "tun.h"
#include "android.h"


#define DNS_ANSWER_SIZE 1024
Expand Down Expand Up @@ -42,7 +43,7 @@ static void dns_recv_cb(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf,
static void close_query(struct dns_query *query);
static void handle_local_dns_answer(struct dns_query *query, uint8_t *buf,
size_t len);
void network_to_tun(int tunfd, uint8_t *buf, ssize_t len);
void tun_write(int tunfd, uint8_t *buf, ssize_t len);


static uint16_t
Expand Down Expand Up @@ -302,5 +303,5 @@ handle_local_dns_answer(struct dns_query *query, uint8_t *answer,
int pktsz = sizeof(struct iphdr) + sizeof(struct udphdr) + answer_len;
uint8_t pkt[pktsz];
create_dns_packet(query, answer, answer_len, pkt);
network_to_tun(query->tunfd, pkt, pktsz);
tun_write(query->tunfd, pkt, pktsz);
}
20 changes: 20 additions & 0 deletions src/common.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <netinet/ip.h>
#include "tun.h"

int
check_incoming_packet(uint8_t *buf, ssize_t len) {
if (sizeof(struct iphdr) + 1 <= len) {
if ((len == sizeof(struct iphdr) + 1) && *buf == 0) { // keepalive
return 1;
}
return -1;
}
return 0;
}

void
construct_keepalive_packet(struct tundev *tun, uint8_t *buf) {
struct iphdr *iphdr = (struct iphdr *)buf;
iphdr->saddr = tun->s_addr;
iphdr->daddr = tun->network;
}
14 changes: 14 additions & 0 deletions src/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef _COMMON_H
#define _COMMON_H

#include <stdint.h>
#include "tun.h"

int check_incoming_packet(uint8_t *buf, ssize_t len);
void construct_keepalive_packet(struct tundev *tun, uint8_t *buf);

#ifdef ANDROID
int protect_socket(int fd);
#endif

#endif // for #ifndef _COMMON_H
43 changes: 26 additions & 17 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

static int mtu = MTU;
static int port = 1082;
static int keepalive = 0;
static int daemon_mode = 1;
static uint32_t parallel = 1;
static char *iface = "tun0";
Expand All @@ -31,23 +32,24 @@ int signal_process(char *signal, const char *pidfile);

static const char *_optString = "i:I:k:c:sb:tp:P:nVvh";
static const struct option _lopts[] = {
{ "", required_argument, NULL, 'i' },
{ "", required_argument, NULL, 'I' },
{ "", required_argument, NULL, 'k' },
{ "client", required_argument, NULL, 'c' },
{ "server", no_argument, NULL, 's' },
{ "port", required_argument, NULL, 'p' },
{ "bind", required_argument, NULL, 'b' },
{ "", required_argument, NULL, 'P' },
{ "tcp", no_argument, NULL, 't' },
{ "mtu", required_argument, NULL, 0 },
{ "pid", required_argument, NULL, 0 },
{ "signal", required_argument, NULL, 0 },
{ "", no_argument, NULL, 'n' },
{ "", no_argument, NULL, 'V' },
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ NULL, no_argument, NULL, 0 }
{ "", required_argument, NULL, 'i' },
{ "", required_argument, NULL, 'I' },
{ "", required_argument, NULL, 'k' },
{ "client", required_argument, NULL, 'c' },
{ "server", no_argument, NULL, 's' },
{ "port", required_argument, NULL, 'p' },
{ "bind", required_argument, NULL, 'b' },
{ "", required_argument, NULL, 'P' },
{ "tcp", no_argument, NULL, 't' },
{ "mtu", required_argument, NULL, 0 },
{ "keepalive", required_argument, NULL, 0 },
{ "pid", required_argument, NULL, 0 },
{ "signal", required_argument, NULL, 0 },
{ "", no_argument, NULL, 'n' },
{ "", no_argument, NULL, 'V' },
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ NULL, no_argument, NULL, 0 }
};


Expand All @@ -67,6 +69,7 @@ print_usage(const char *prog) {
" [-P <parallel>]\t number of parallel tun queues (only available on server mode & UDP)\n"
" [--pid <pid>]\t\t PID file of daemon (default: /var/run/xTun.pid)\n"
" [--mtu <mtu>]\t\t MTU size (default: 1426)\n"
" [--keepalive <second>] keepalive delay (default: 0)\n"
" [--signal <signal>]\t send signal to xTun: quit, stop\n"
" [-t --tcp]\t\t use TCP rather than UDP (only available on client mode)\n"
" [-n]\t\t\t non daemon mode\n"
Expand Down Expand Up @@ -144,6 +147,9 @@ parse_opts(int argc, char *argv[]) {
mtu = MTU;
}
}
if (strcmp("keepalive", _lopts[longindex].name) == 0) {
keepalive = strtol(optarg, NULL, 10);
}
if (strcmp("pid", _lopts[longindex].name) == 0) {
pidfile = optarg;
}
Expand Down Expand Up @@ -222,6 +228,9 @@ main(int argc, char *argv[]) {
}

tun_config(tun, ifconf, mtu, &addr);
if (keepalive) {
tun_keepalive(tun, 1, keepalive);
}
tun_start(tun);

tun_free(tun);
Expand Down
4 changes: 2 additions & 2 deletions src/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ send_cb(uv_write_t *req, int status) {
}

void
tun_to_tcp(uint8_t *buf, int len, uv_stream_t *stream) {
tcp_send(uv_stream_t *stream, uint8_t *buf, int len) {
uint8_t *hdr = malloc(HEADER_BYTES);
write_size(hdr, len);

Expand All @@ -38,4 +38,4 @@ tun_to_tcp(uint8_t *buf, int len, uv_stream_t *stream) {
logger_log(LOG_ERR, "TCP Write error: %s", uv_strerror(rc));
free(buf);
}
}
}
17 changes: 17 additions & 0 deletions src/tcp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef _TCP_H
#define _TCP_H

#include "uv.h"

int tcp_client_start(struct tundev_context *ctx, uv_loop_t *loop);
void tcp_client_stop(struct tundev_context *ctx);
void tcp_client_connect(struct tundev_context *ctx);
void tcp_client_send(struct tundev_context *ctx, uint8_t *buf, int len);

int tcp_server_start(struct tundev_context *ctx, uv_loop_t *loop);
void tcp_server_stop(struct tundev_context *ctx);
void tcp_server_send(struct peer *peer, uint8_t *buf, int len);

void tcp_send(uv_stream_t *stream, uint8_t *buf, int len);

#endif // for #ifndef _TCP_H
59 changes: 47 additions & 12 deletions src/tcp_client.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#include "assert.h"
#include <assert.h>
#include "uv.h"

#include "common.h"
#include "crypto.h"
#include "logger.h"
#include "packet.h"
#include "util.h"
#include "tun.h"
#include "tcp.h"
#ifdef ANDROID
#include "android.h"
#endif
Expand All @@ -14,16 +16,16 @@
static void
timer_expire(uv_timer_t *handle) {
struct tundev_context *ctx = container_of(handle, struct tundev_context,
timer);
connect_to_server(ctx);
timer_reconnect);
tcp_client_connect(ctx);
}

static void
reconnect(struct tundev_context *ctx) {
ctx->interval *= 2;
int timeout = ctx->interval < MAX_RETRY_INTERVAL ?
ctx->interval : MAX_RETRY_INTERVAL;
uv_timer_start(&ctx->timer, timer_expire, timeout * 1000, 0);
uv_timer_start(&ctx->timer_reconnect, timer_expire, timeout * 1000, 0);
}

static void
Expand Down Expand Up @@ -70,7 +72,7 @@ recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
goto err;
}

network_to_tun(ctx->tunfd, m, mlen);
tun_write(ctx->tunfd, m, mlen);

packet_reset(packet);

Expand Down Expand Up @@ -98,14 +100,31 @@ receive_from_server(struct tundev_context *ctx) {
uv_read_start(&ctx->inet_tcp.stream, alloc_cb, recv_cb);
}

static void
keepalive(uv_timer_t *handle) {
struct tundev_context *ctx = container_of(handle, struct tundev_context,
timer_keepalive);
if (ctx->connect != CONNECTED) {
if (ctx->connect == DISCONNECTED) {
tcp_client_connect(ctx);
}
return;
}
size_t len = sizeof(struct iphdr) + PRIMITIVE_BYTES + 1;
uint8_t *buf = calloc(1, len);
construct_keepalive_packet(ctx->tun, buf + PRIMITIVE_BYTES);
crypto_encrypt(buf, buf + PRIMITIVE_BYTES, len - PRIMITIVE_BYTES);
tcp_send(&ctx->inet_tcp.stream, buf, len);
}

static void
connect_cb(uv_connect_t *req, int status) {
struct tundev_context *ctx = container_of(req, struct tundev_context,
connect_req);
if (status == 0) {
ctx->interval = 5;
ctx->connect = CONNECTED;
uv_timer_stop(&ctx->timer);
uv_timer_stop(&ctx->timer_reconnect);
receive_from_server(ctx);
} else {
if (status != UV_ECANCELED) {
Expand All @@ -118,10 +137,10 @@ connect_cb(uv_connect_t *req, int status) {
}

void
connect_to_server(struct tundev_context *ctx) {
tcp_client_connect(struct tundev_context *ctx) {
int rc;

uv_tcp_init(ctx->timer.loop, &ctx->inet_tcp.tcp);
uv_tcp_init(ctx->timer_reconnect.loop, &ctx->inet_tcp.tcp);

ctx->inet_tcp_fd = create_socket(SOCK_STREAM, 0);
if ((rc = uv_tcp_open(&ctx->inet_tcp.tcp, ctx->inet_tcp_fd))) {
Expand Down Expand Up @@ -155,12 +174,28 @@ tcp_client_start(struct tundev_context *ctx, uv_loop_t *loop) {
ctx->packet.buf = malloc(PRIMITIVE_BYTES + ctx->tun->mtu);
ctx->packet.max = PRIMITIVE_BYTES + ctx->tun->mtu;
packet_reset(&ctx->packet);
uv_timer_init(loop, &ctx->timer);
connect_to_server(ctx);
uv_timer_init(loop, &ctx->timer_reconnect);
if (ctx->tun->keepalive_delay) {
uint64_t timeout = ctx->tun->keepalive_delay * 1000;
uv_timer_init(loop, &ctx->timer_keepalive);
uv_timer_start(&ctx->timer_keepalive, keepalive, timeout, timeout);
}
tcp_client_connect(ctx);
return 0;
}

void
tun_to_tcp_server(struct tundev_context *ctx, uint8_t *buf, int len) {
tun_to_tcp(buf, len, &ctx->inet_tcp.stream);
tcp_client_stop(struct tundev_context *ctx) {
if (uv_is_active(&ctx->inet_tcp.handle)) {
uv_close(&ctx->inet_tcp.handle, NULL);
}
uv_close((uv_handle_t *) &ctx->timer_reconnect, NULL);
if (ctx->tun->keepalive_delay) {
uv_close((uv_handle_t *) &ctx->timer_keepalive, NULL);
}
}

void
tcp_client_send(struct tundev_context *ctx, uint8_t *buf, int len) {
tcp_send(&ctx->inet_tcp.stream, buf, len);
}
Loading

0 comments on commit e922add

Please sign in to comment.