Compare commits

..

19 Commits

Author SHA1 Message Date
Adrien Gallouët
0a797b4f5f Try value 42 for mptcp (fallback to 26) 2017-06-07 11:27:44 +02:00
Adrien Gallouët
8cb849fbc3 Update pkg.m4 2017-06-07 11:26:22 +02:00
Adrien Gallouët
13f9f4c896 Fix printf format 2016-07-20 15:32:22 +00:00
Adrien Gallouët
cfd7af9241 Add .build.sh 2016-07-11 11:13:29 +00:00
Adrien Gallouët
c81592fcc5 Don't fd_set_nonblock(-1) 2016-06-23 12:15:01 +00:00
Adrien Gallouët
b4a311cdc8 Check for clock_gettime() 2016-06-15 14:12:21 +00:00
Adrien Gallouët
08617d0017 Fix macosx build 2016-06-15 14:01:20 +00:00
Adrien Gallouët
38cd3b0371 Try to do a more accurate bench 2016-06-15 09:20:18 +00:00
Adrien Gallouët
5944e61dfe Fix bench output 2016-06-15 09:10:57 +00:00
Adrien Gallouët
585b2b08bc Be more verbose on kx errors 2016-06-06 13:37:05 +00:00
angt
a3aa6fc4fb Add option bench 2016-06-02 13:44:24 +00:00
angt
6f36424d12 Code cleanup 2016-04-26 06:18:12 +00:00
angt
fa9301da16 Show tun_name in all states and fix state_send() 2016-04-26 06:13:14 +00:00
angt
c154a00358 Use a bigger timeout when buffers are empty 2016-04-12 14:11:16 +00:00
Adrien Gallouët
4246b510d2 Never trust frank :) 2016-03-30 15:41:53 +02:00
Adrien Gallouët
c71db48ae1 Add a nice geek logo for glorytun 2016-03-23 17:44:40 +01:00
Adrien Gallouët
e3cce8aeb9 AES-NI is no longer mandatory 2016-03-18 21:19:24 +01:00
angt
ad0d205ff3 Add option chacha20
Chacha20 will be automatically used if aesni is not available.
2016-03-18 14:43:30 +00:00
angt
030087cb27 Add mptcp option 2016-02-25 14:38:51 +00:00
14 changed files with 1546 additions and 498 deletions

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule "mud"]
path = mud
url = https://github.com/angt/mud.git

View File

@@ -20,11 +20,6 @@ glorytun_SOURCES = \
src/state.c \ src/state.c \
src/state.h src/state.h
glorytun_CFLAGS += -I$(srcdir)/mud
glorytun_SOURCES += \
mud/mud.h \
mud/mud.c
EXTRA_DIST = \ EXTRA_DIST = \
LICENSE \ LICENSE \
README.md \ README.md \

View File

@@ -1,6 +1,6 @@
# π₁(Glorytun)=ℤ² # π₁(Glorytun)=ℤ²
Small, Simple and Stupid VPN over [mud](https://github.com/angt/mud). Small, Simple and Stupid TCP VPN.
#### Work In Progress #### Work In Progress
@@ -8,12 +8,11 @@ This code will probably format your harddisk!
#### Build and Install #### Build and Install
Glorytun depends on [libsodium](https://github.com/jedisct1/libsodium) version >= 1.0.4 Glorytun depends on [libsodium](https://github.com/jedisct1/libsodium) version >= 1.0.4.
and needs an AES-NI capable CPU.
To build and install the latest version: To build and install the latest version:
$ git clone https://github.com/angt/glorytun --recursive --branch mud $ git clone https://github.com/angt/glorytun
$ cd glorytun $ cd glorytun
$ ./autogen.sh $ ./autogen.sh
$ ./configure $ ./configure

View File

@@ -14,6 +14,7 @@ AM_SILENT_RULES([yes])
AM_PROG_CC_C_O AM_PROG_CC_C_O
AC_PROG_CC_C99 AC_PROG_CC_C99
AC_USE_SYSTEM_EXTENSIONS AC_USE_SYSTEM_EXTENSIONS
AC_SEARCH_LIBS([getaddrinfo], [resolv nsl])
AC_SEARCH_LIBS([socket], [socket]) AC_SEARCH_LIBS([socket], [socket])
AC_CHECK_LIB([rt], [clock_gettime]) AC_CHECK_LIB([rt], [clock_gettime])
AC_CHECK_FUNCS([clock_gettime]) AC_CHECK_FUNCS([clock_gettime])

View File

@@ -1,6 +1,6 @@
dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
dnl serial 11 (pkg-config-0.29) # serial 12 (pkg-config-0.29.2)
dnl
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
dnl dnl
@@ -41,7 +41,7 @@ dnl
dnl See the "Since" comment for each macro you use to see what version dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require. dnl of the macros you require.
m4_defun([PKG_PREREQ], m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29]) [m4_define([PKG_MACROS_VERSION], [0.29.2])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ ])dnl PKG_PREREQ
@@ -142,7 +142,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no pkg_failed=no
AC_MSG_CHECKING([for $1]) AC_MSG_CHECKING([for $2])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2])
@@ -152,11 +152,11 @@ and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.]) See the pkg-config man page for more details.])
if test $pkg_failed = yes; then if test $pkg_failed = yes; then
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED _PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi fi
# Put the nasty error message in config.log where it belongs # Put the nasty error message in config.log where it belongs
@@ -173,7 +173,7 @@ installed software in a non-standard prefix.
_PKG_TEXT])[]dnl _PKG_TEXT])[]dnl
]) ])
elif test $pkg_failed = untried; then elif test $pkg_failed = untried; then
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE( m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it [The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full is in your PATH or set the PKG_CONFIG environment variable to the full

1
mud

Submodule mud deleted from 078a30611e

View File

@@ -1,24 +1,22 @@
#include "common.h" #include "common.h"
#include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h>
int int gt_print (const char *fmt, ...)
gt_print(const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
int ret = vfprintf(stdout, fmt, ap); int ret = vfprintf(stdout, fmt, ap);
va_end(ap); va_end(ap);
if (ret < 0) if (ret<0)
return 0; return 0;
return ret; return ret;
} }
void void gt_log (const char *fmt, ...)
gt_log(const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
@@ -26,8 +24,7 @@ gt_log(const char *fmt, ...)
va_end(ap); va_end(ap);
} }
void void gt_fatal (const char *fmt, ...)
gt_fatal(const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
@@ -37,26 +34,24 @@ gt_fatal(const char *fmt, ...)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
void void gt_na (const char *name)
gt_na(const char *name)
{ {
gt_log("%s is not available on your platform\n", name); gt_log("%s is not available on your platform\n", name);
} }
int int gt_tohex (char *dst, size_t dst_size, const uint8_t *src, size_t src_size)
gt_tohex(char *dst, size_t dst_size, const uint8_t *src, size_t src_size)
{ {
if (_0_(!dst_size)) if _0_(!dst_size)
return -1; return -1;
if (_0_(((dst_size - 1) / 2) < src_size)) if _0_(((dst_size-1)/2)<src_size)
return -1; return -1;
static const char tbl[] = "0123456789ABCDEF"; static const char tbl[] = "0123456789ABCDEF";
for (size_t i = 0; i < src_size; i++) { for (size_t i=0; i<src_size; i++) {
*dst++ = tbl[0xF & (src[i] >> 4)]; *dst++ = tbl[0xF&(src[i]>>4)];
*dst++ = tbl[0xF & (src[i])]; *dst++ = tbl[0xF&(src[i])];
} }
*dst = 0; *dst = 0;
@@ -64,38 +59,37 @@ gt_tohex(char *dst, size_t dst_size, const uint8_t *src, size_t src_size)
return 0; return 0;
} }
_const_ static inline int _const_
fromhex(const char c) static inline int fromhex (const char c)
{ {
if (c >= '0' && c <= '9') if (c>='0' && c<='9')
return c - '0'; return c-'0';
if (c >= 'A' && c <= 'F') if (c>='A' && c<='F')
return c - 'A' + 10; return c-'A'+10;
if (c >= 'a' && c <= 'f') if (c>='a' && c<='f')
return c - 'a' + 10; return c-'a'+10;
return -1; return -1;
} }
int int gt_fromhex (uint8_t *dst, size_t dst_size, const char *src, size_t src_size)
gt_fromhex(uint8_t *dst, size_t dst_size, const char *src, size_t src_size)
{ {
if (_0_(src_size & 1)) if _0_(src_size&1)
return -1; return -1;
if (_0_(dst_size < (src_size / 2))) if _0_(dst_size<(src_size/2))
return -1; return -1;
for (size_t i = 0; i < src_size; i += 2) { for (size_t i=0; i<src_size; i+=2) {
const int a = fromhex(src[i]); const int a = fromhex(src[i]);
const int b = fromhex(src[i + 1]); const int b = fromhex(src[i+1]);
if (_0_(a == -1 || b == -1)) if _0_(a==-1 || b==-1)
return -1; return -1;
*dst++ = (a << 4) | b; *dst++ = (a<<4)|b;
} }
return 0; return 0;

View File

@@ -3,57 +3,56 @@
#include "db.h" #include "db.h"
#include "str.h" #include "str.h"
#define CBIT(X) (1 & (intptr_t)(X)) #define CBIT(X) (1&(intptr_t)(X))
#define CBIT_PTR(X) (uint8_t *)(1 | (intptr_t)(X)) #define CBIT_PTR(X) (uint8_t *)(1|(intptr_t)(X))
#define CBIT_NODE(X) (struct node *)(1 ^ (intptr_t)(X)) #define CBIT_NODE(X) (struct node *)(1^(intptr_t)(X))
struct node { struct node {
uint8_t *child[2]; uint8_t *child[2];
uint32_t point; uint32_t point;
}; };
_pure_ static inline size_t _pure_
db_size(const uint8_t *a) static inline size_t db_size (const uint8_t *a)
{ {
return (a[0] ?: str_len((char *)a + 1)) + 1; return (a[0]?:str_len((char *)a+1))+1;
} }
_pure_ static inline size_t _pure_
db_cmp(const uint8_t *a, const uint8_t *b) static inline size_t db_cmp (const uint8_t *a, const uint8_t *b)
{ {
const size_t size = a[0]; const size_t size = a[0];
if (size != b[0]) if (size!=b[0])
return 1; return 1;
if (!size) { if (!size) {
size_t i = str_cmp((char *)a + 1, (char *)b + 1); size_t i = str_cmp((char *)a+1, (char *)b+1);
return i ? i + 1 : 0; return i?i+1:0;
} }
for (size_t i = 1; i <= size; i++) { for (size_t i=1; i<=size; i++) {
if (a[i] != b[i]) if (a[i]!=b[i])
return i + 1; return i+1;
} }
return 0; return 0;
} }
_pure_ static inline int _pure_
db_dir(const uint32_t point, uint8_t *data, const size_t size) static inline int db_dir (const uint32_t point, uint8_t *data, const size_t size)
{ {
const size_t pos = point >> 8; const size_t pos = point>>8;
if (pos >= size) if (pos>=size)
return 0; return 0;
return ((point | data[pos]) & 255) == 255; return ((point|data[pos])&255)==255;
} }
uint8_t * uint8_t *db_search (uint8_t **p, uint8_t *data)
db_search(uint8_t **p, uint8_t *data)
{ {
if (_0_(!*p)) if _0_(!*p)
return NULL; return NULL;
uint8_t *r = *p; uint8_t *r = *p;
@@ -70,13 +69,12 @@ db_search(uint8_t **p, uint8_t *data)
return NULL; return NULL;
} }
uint8_t * uint8_t *db_insert (uint8_t **p, uint8_t *data)
db_insert(uint8_t **p, uint8_t *data)
{ {
if (_0_(CBIT(data))) if _0_(CBIT(data))
return NULL; return NULL;
if (_0_(!*p)) { if _0_(!*p) {
*p = data; *p = data;
return data; return data;
} }
@@ -91,31 +89,31 @@ db_insert(uint8_t **p, uint8_t *data)
const size_t diff = db_cmp(r, data); const size_t diff = db_cmp(r, data);
if (_0_(!diff)) if _0_(!diff)
return r; return r;
const size_t pos = diff - 1; const size_t pos = diff-1;
const uint8_t mask = ~((1u << 31) >> CLZ(r[pos] ^ data[pos])); const uint8_t mask = ~((1u<<31)>>CLZ(r[pos]^data[pos]));
const size_t point = (pos << 8) | mask; const size_t point = (pos<<8)|mask;
while (CBIT(*p)) { while (CBIT(*p)) {
struct node *node = CBIT_NODE(*p); struct node *node = CBIT_NODE(*p);
if (node->point > point) if (node->point>point)
break; break;
p = node->child + db_dir(node->point, data, size); p = node->child+db_dir(node->point, data, size);
} }
struct node *node = malloc(sizeof(struct node)); struct node *node = malloc(sizeof(struct node));
if (_0_(!node)) if _0_(!node)
return NULL; return NULL;
const int dir = (mask | r[pos]) == 255; const int dir = (mask|r[pos])==255;
node->child[dir] = *p; node->child[dir] = *p;
node->child[1 - dir] = data; node->child[1-dir] = data;
node->point = point; node->point = point;
*p = CBIT_PTR(node); *p = CBIT_PTR(node);
@@ -123,10 +121,9 @@ db_insert(uint8_t **p, uint8_t *data)
return data; return data;
} }
uint8_t * uint8_t *db_remove (uint8_t **p, uint8_t *data)
db_remove(uint8_t **p, uint8_t *data)
{ {
if (_0_(!*p)) if _0_(!*p)
return NULL; return NULL;
const size_t size = db_size(data); const size_t size = db_size(data);
@@ -139,16 +136,16 @@ db_remove(uint8_t **p, uint8_t *data)
p_old = p; p_old = p;
node = CBIT_NODE(*p); node = CBIT_NODE(*p);
dir = db_dir(node->point, data, size); dir = db_dir(node->point, data, size);
p = node->child + dir; p = node->child+dir;
} }
if (_0_(db_cmp(data, *p))) if _0_(db_cmp(data, *p))
return NULL; return NULL;
uint8_t *r = *p; uint8_t *r = *p;
if (p_old) { if (p_old) {
*p_old = node->child[1 - dir]; *p_old = node->child[1-dir];
free(node); free(node);
} else { } else {
*p = NULL; *p = NULL;

View File

@@ -4,7 +4,6 @@
struct ip_common { struct ip_common {
uint8_t version; uint8_t version;
uint8_t tc;
uint8_t proto; uint8_t proto;
uint8_t hdr_size; uint8_t hdr_size;
uint16_t size; uint16_t size;
@@ -25,13 +24,11 @@ static inline int ip_get_common (struct ip_common *ic, const uint8_t *data, size
switch (ic->version) { switch (ic->version) {
case 4: case 4:
ic->tc = data[1];
ic->proto = data[9]; ic->proto = data[9];
ic->hdr_size = (data[0]&0xF)<<2; ic->hdr_size = (data[0]&0xF)<<2;
ic->size = ((data[2]<<8)|data[3]); ic->size = ((data[2]<<8)|data[3]);
return 0; return 0;
case 6: case 6:
ic->tc = ((data[0]&0xF)<<4)|(data[1]>>4);
ic->proto = data[6]; ic->proto = data[6];
ic->hdr_size = 40; ic->hdr_size = 40;
ic->size = ((data[4]<<8)|data[5])+40; ic->size = ((data[4]<<8)|data[5])+40;

1651
src/main.c

File diff suppressed because it is too large Load Diff

View File

@@ -3,10 +3,9 @@
#include "option.h" #include "option.h"
#include "str.h" #include "str.h"
int int option_str (void *data, int argc, char **argv)
option_str(void *data, int argc, char **argv)
{ {
if (argc < 2 || str_empty(argv[1])) { if (argc<2 || str_empty(argv[1])) {
gt_print("option `%s' need a string argument\n", argv[0]); gt_print("option `%s' need a string argument\n", argv[0]);
return -1; return -1;
} }
@@ -16,10 +15,9 @@ option_str(void *data, int argc, char **argv)
return 1; return 1;
} }
int int option_long (void *data, int argc, char **argv)
option_long(void *data, int argc, char **argv)
{ {
if (argc < 2 || str_empty(argv[1])) { if (argc<2 || str_empty(argv[1])) {
gt_print("option `%s' need an integer argument\n", argv[0]); gt_print("option `%s' need an integer argument\n", argv[0]);
return -1; return -1;
} }
@@ -28,7 +26,7 @@ option_long(void *data, int argc, char **argv)
char *end; char *end;
long val = strtol(argv[1], &end, 0); long val = strtol(argv[1], &end, 0);
if (errno || argv[1] == end) { if (errno || argv[1]==end) {
gt_print("argument `%s' is not a valid integer\n", argv[1]); gt_print("argument `%s' is not a valid integer\n", argv[1]);
return -1; return -1;
} }
@@ -38,10 +36,9 @@ option_long(void *data, int argc, char **argv)
return 1; return 1;
} }
int int option_is_set (struct option *opts, const char *name)
option_is_set(struct option *opts, const char *name)
{ {
for (int k = 0; opts[k].name; k++) { for (int k=0; opts[k].name; k++) {
if (!str_cmp(opts[k].name, name)) if (!str_cmp(opts[k].name, name))
return opts[k].set; return opts[k].set;
} }
@@ -49,21 +46,20 @@ option_is_set(struct option *opts, const char *name)
return 0; return 0;
} }
int int option_option (void *data, int argc, char **argv)
option_option(void *data, int argc, char **argv)
{ {
if (!data) if (!data)
return 0; return 0;
struct option *opts = (struct option *)data; struct option *opts = (struct option *)data;
for (int k = 0; opts[k].name; k++) for (int k=0; opts[k].name; k++)
opts[k].set = 0; opts[k].set = 0;
for (int i = 1; i < argc; i++) { for (int i=1; i<argc; i++) {
int found = 0; int found = 0;
for (int k = 0; opts[k].name; k++) { for (int k=0; opts[k].name; k++) {
if (str_cmp(opts[k].name, argv[i])) if (str_cmp(opts[k].name, argv[i]))
continue; continue;
@@ -72,9 +68,9 @@ option_option(void *data, int argc, char **argv)
return -1; return -1;
} }
int ret = opts[k].call(opts[k].data, argc - i, &argv[i]); int ret = opts[k].call(opts[k].data, argc-i, &argv[i]);
if (ret < 0) if (ret<0)
return -1; return -1;
opts[k].set = 1; opts[k].set = 1;
@@ -85,30 +81,29 @@ option_option(void *data, int argc, char **argv)
} }
if (!found) if (!found)
return i - 1; return i-1;
} }
return argc; return argc;
} }
static int static int option_usage (struct option *opts, int slen)
option_usage(struct option *opts, int slen)
{ {
if (!opts) if (!opts)
return 0; return 0;
int len = 0; int len = 0;
for (int k = 0; opts[k].name; k++) { for (int k=0; opts[k].name; k++) {
if (len > 40) { if (len>40) {
gt_print("\n%*s", slen, ""); gt_print("\n%*s", slen, "");
len = 0; len = 0;
} }
len += gt_print(" [%s", opts[k].name); len += gt_print(" [%s", opts[k].name);
if (opts[k].call == option_option) { if (opts[k].call==option_option) {
len += option_usage((struct option *)opts[k].data, slen + len); len += option_usage((struct option *)opts[k].data, slen+len);
} else { } else {
len += gt_print(" ARG"); len += gt_print(" ARG");
} }
@@ -119,22 +114,21 @@ option_usage(struct option *opts, int slen)
return len; return len;
} }
int int option (struct option *opts, int argc, char **argv)
option(struct option *opts, int argc, char **argv)
{ {
int ret = option_option(opts, argc, argv); int ret = option_option(opts, argc, argv);
if (ret == argc) if (ret==argc)
return 0; return 0;
if (ret < 0 || ret + 1 >= argc) if (ret<0 || ret+1>=argc)
return 1; return 1;
gt_print("option `%s' is unknown\n", argv[ret + 1]); gt_print("option `%s' is unknown\n", argv[ret+1]);
int slen = gt_print("usage: %s", argv[0]); int slen = gt_print("usage: %s", argv[0]);
if (slen > 40) { if (slen>40) {
slen = 12; slen = 12;
gt_print("\n%*s", slen, ""); gt_print("\n%*s", slen, "");
} }

View File

@@ -3,27 +3,26 @@
#include "state.h" #include "state.h"
#include "str.h" #include "str.h"
#include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
int int state_create (const char *filename)
state_create(const char *filename)
{ {
if (str_empty(filename)) if (str_empty(filename))
return -1; return -1;
int fd = open(filename, O_WRONLY); int fd = open(filename, O_WRONLY);
if (fd == -1) { if (fd==-1) {
if (errno != EINTR) if (errno!=EINTR)
perror("open"); perror("open");
return -1; return -1;
} }
struct stat st = {0}; struct stat st = {0};
if (fstat(fd, &st) == -1) { if (fstat(fd, &st)==-1) {
perror("fstat"); perror("fstat");
close(fd); close(fd);
return -1; return -1;
@@ -38,18 +37,17 @@ state_create(const char *filename)
return fd; return fd;
} }
void void state_send (int fd, const char *state, const char *info)
state_send(int fd, const char *state, const char *info)
{ {
if (str_empty(state)) if (str_empty(state))
return; return;
if (fd == -1) { if (fd==-1) {
gt_print("%s %s\n", state, info); gt_print("%s %s\n", state, info);
return; return;
} }
const char *strs[] = {state, " ", info, "\n"}; const char *strs[] = { state, " ", info, "\n" };
char *str = str_cat(strs, COUNT(strs)); char *str = str_cat(strs, COUNT(strs));
if (!str) { if (!str) {
@@ -57,7 +55,7 @@ state_send(int fd, const char *state, const char *info)
return; return;
} }
if (write(fd, str, str_len(str)) == -1 && errno != EINTR) if (write(fd, str, str_len(str))==-1 && errno!=EINTR)
perror("write"); perror("write");
free(str); free(str);

137
src/tun.c
View File

@@ -1,26 +1,25 @@
#include "common.h" #include "common.h"
#include "ip.h"
#include "str.h"
#include "tun.h" #include "tun.h"
#include "str.h"
#include "ip.h"
#include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <net/if.h>
#ifdef __linux__ #ifdef __linux__
#include <linux/if.h>
#include <linux/if_tun.h> #include <linux/if_tun.h>
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
#include <net/if_utun.h>
#include <sys/kern_control.h>
#include <sys/sys_domain.h> #include <sys/sys_domain.h>
#include <sys/kern_control.h>
#include <net/if_utun.h>
#endif #endif
#if defined(__APPLE__) || defined(__OpenBSD__) #if defined(__APPLE__) || defined(__OpenBSD__)
@@ -29,18 +28,17 @@
#ifdef __APPLE__ #ifdef __APPLE__
static int static int tun_create_by_id (char *name, size_t size, unsigned id, _unused_ int mq)
tun_create_by_id(char *name, size_t size, unsigned id)
{ {
int fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL); int fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
if (fd == -1) if (fd==-1)
return -1; return -1;
struct ctl_info ci; struct ctl_info ci;
memset(&ci, 0, sizeof(ci)); memset(&ci, 0, sizeof(ci));
str_cpy(ci.ctl_name, UTUN_CONTROL_NAME, sizeof(ci.ctl_name) - 1); str_cpy(ci.ctl_name, UTUN_CONTROL_NAME, sizeof(ci.ctl_name)-1);
if (ioctl(fd, CTLIOCGINFO, &ci)) { if (ioctl(fd, CTLIOCGINFO, &ci)) {
close(fd); close(fd);
@@ -52,7 +50,7 @@ tun_create_by_id(char *name, size_t size, unsigned id)
.sc_len = sizeof(sc), .sc_len = sizeof(sc),
.sc_family = AF_SYSTEM, .sc_family = AF_SYSTEM,
.ss_sysaddr = AF_SYS_CONTROL, .ss_sysaddr = AF_SYS_CONTROL,
.sc_unit = id + 1, .sc_unit = id+1,
}; };
if (connect(fd, (struct sockaddr *)&sc, sizeof(sc))) { if (connect(fd, (struct sockaddr *)&sc, sizeof(sc))) {
@@ -65,93 +63,98 @@ tun_create_by_id(char *name, size_t size, unsigned id)
return fd; return fd;
} }
static int static int tun_create_by_name (char *name, size_t size, char *dev_name, int mq)
tun_create_by_name(char *name, size_t size, char *dev_name)
{ {
unsigned id = 0; unsigned id = 0;
if (sscanf(dev_name, "utun%u", &id) != 1) if (sscanf(dev_name, "utun%u", &id)!=1)
return -1; return -1;
return tun_create_by_id(name, size, id); return tun_create_by_id(name, size, id, mq);
} }
#else /* not __APPLE__ */ #else /* not __APPLE__ */
#ifdef __linux__ #ifdef __linux__
static int static int tun_create_by_name (char *name, size_t size, char *dev_name, int mq)
tun_create_by_name(char *name, size_t size, char *dev_name)
{ {
int fd = open("/dev/net/tun", O_RDWR); int fd = open("/dev/net/tun", O_RDWR);
if (fd == -1) if (fd==-1)
return -1; return -1;
struct ifreq ifr = { struct ifreq ifr = {
.ifr_flags = IFF_TUN | IFF_NO_PI, .ifr_flags = IFF_TUN|IFF_NO_PI,
}; };
str_cpy(ifr.ifr_name, dev_name, IFNAMSIZ - 1); if (mq) {
#ifdef IFF_MULTI_QUEUE
ifr.ifr_flags |= IFF_MULTI_QUEUE;
#endif
}
str_cpy(ifr.ifr_name, dev_name, IFNAMSIZ-1);
if (ioctl(fd, TUNSETIFF, &ifr)) { if (ioctl(fd, TUNSETIFF, &ifr)) {
close(fd); close(fd);
return -1; return -1;
} }
str_cpy(name, ifr.ifr_name, size - 1); str_cpy(name, ifr.ifr_name, size-1);
return fd; return fd;
} }
#else /* not __linux__ not __APPLE__ */ #else /* not __linux__ not __APPLE__ */
static int static int tun_create_by_name (char *name, size_t size, char *dev_name, _unused_ int mq)
tun_create_by_name(char *name, size_t size, char *dev_name)
{ {
char path[64]; char path[64];
snprintf(path, sizeof(path), "/dev/%s", dev_name); snprintf(path, sizeof(path), "/dev/%s", dev_name);
str_cpy(name, dev_name, size - 1); str_cpy(name, dev_name, size-1);
return open(path, O_RDWR); return open(path, O_RDWR);
} }
#endif /* not __APPLE__ */ #endif /* not __APPLE__ */
static int static int tun_create_by_id (char *name, size_t size, unsigned id, int mq)
tun_create_by_id(char *name, size_t size, unsigned id)
{ {
char dev_name[64]; char dev_name[64];
snprintf(dev_name, sizeof(dev_name), "tun%u", id); snprintf(dev_name, sizeof(dev_name), "tun%u", id);
return tun_create_by_name(name, size, dev_name); return tun_create_by_name(name, size, dev_name, mq);
} }
#endif #endif
int int tun_create (char *dev_name, char **ret_name, int mq)
tun_create(char *dev_name, char **ret_name)
{ {
char name[64] = {0}; char name[64] = {0};
int fd = -1; int fd = -1;
#ifndef IFF_MULTI_QUEUE
if (mq)
gt_na("IFF_MULTI_QUEUE");
#endif
if (str_empty(dev_name)) { if (str_empty(dev_name)) {
for (unsigned id = 0; id < 32 && fd == -1; id++) for (unsigned id=0; id<32 && fd==-1; id++)
fd = tun_create_by_id(name, sizeof(name), id); fd = tun_create_by_id(name, sizeof(name), id, mq);
} else { } else {
fd = tun_create_by_name(name, sizeof(name), dev_name); fd = tun_create_by_name(name, sizeof(name), dev_name, mq);
} }
if (fd != -1 && ret_name) if (fd!=-1 && ret_name)
*ret_name = strdup(name); *ret_name = strdup(name);
return fd; return fd;
} }
ssize_t ssize_t tun_read (int fd, void *data, size_t size)
tun_read(int fd, void *data, size_t size)
{ {
if (!size) if (!size)
return -1; return -1;
@@ -160,14 +163,8 @@ tun_read(int fd, void *data, size_t size)
uint32_t family; uint32_t family;
struct iovec iov[2] = { struct iovec iov[2] = {
{ { .iov_base = &family, .iov_len = sizeof(family) },
.iov_base = &family, { .iov_base = data, .iov_len = size }
.iov_len = sizeof(family),
},
{
.iov_base = data,
.iov_len = size,
},
}; };
ssize_t ret = readv(fd, iov, 2); ssize_t ret = readv(fd, iov, 2);
@@ -175,8 +172,8 @@ tun_read(int fd, void *data, size_t size)
ssize_t ret = read(fd, data, size); ssize_t ret = read(fd, data, size);
#endif #endif
if (ret == -1) { if (ret==-1) {
if (errno == EAGAIN || errno == EINTR) if (errno==EAGAIN || errno==EINTR)
return -1; return -1;
if (errno) if (errno)
@@ -186,17 +183,16 @@ tun_read(int fd, void *data, size_t size)
} }
#ifdef GT_BSD_TUN #ifdef GT_BSD_TUN
if (ret < (ssize_t)sizeof(family)) if (ret<(ssize_t) sizeof(family))
return 0; return 0;
return ret - sizeof(family); return ret-sizeof(family);
#else #else
return ret; return ret;
#endif #endif
} }
ssize_t ssize_t tun_write (int fd, const void *data, size_t size)
tun_write(int fd, const void *data, size_t size)
{ {
if (!size) if (!size)
return -1; return -1;
@@ -216,14 +212,8 @@ tun_write(int fd, const void *data, size_t size)
} }
struct iovec iov[2] = { struct iovec iov[2] = {
{ { .iov_base = &family, .iov_len = sizeof(family) },
.iov_base = &family, { .iov_base = (void *) data, .iov_len = size },
.iov_len = sizeof(family),
},
{
.iov_base = (void *)data,
.iov_len = size,
},
}; };
ssize_t ret = writev(fd, iov, 2); ssize_t ret = writev(fd, iov, 2);
@@ -231,8 +221,8 @@ tun_write(int fd, const void *data, size_t size)
ssize_t ret = write(fd, data, size); ssize_t ret = write(fd, data, size);
#endif #endif
if (ret == -1) { if (ret==-1) {
if (errno == EAGAIN || errno == EINTR) if (errno==EAGAIN || errno==EINTR)
return -1; return -1;
if (errno) if (errno)
@@ -242,34 +232,11 @@ tun_write(int fd, const void *data, size_t size)
} }
#ifdef GT_BSD_TUN #ifdef GT_BSD_TUN
if (ret < (ssize_t)sizeof(family)) if (ret<(ssize_t) sizeof(family))
return 0; return 0;
return ret - sizeof(family); return ret-sizeof(family);
#else #else
return ret; return ret;
#endif #endif
} }
int
tun_set_mtu(char *dev_name, int mtu)
{
struct ifreq ifr = {
.ifr_mtu = mtu,
};
str_cpy(ifr.ifr_name, dev_name, IFNAMSIZ - 1);
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd == -1)
return -1;
int ret = ioctl(fd, SIOCSIFMTU, &ifr);
int err = errno;
close(fd);
errno = err;
return ret;
}

View File

@@ -2,7 +2,6 @@
#include <unistd.h> #include <unistd.h>
int tun_create (char *, char **); int tun_create (char *, char **, int);
ssize_t tun_read (int, void *, size_t); ssize_t tun_read (int, void *, size_t);
ssize_t tun_write (int, const void *, size_t); ssize_t tun_write (int, const void *, size_t);
int tun_set_mtu (char *, int);