Compare commits

..

82 Commits

Author SHA1 Message Date
angt
72d771e126 Key exchange may fail for several reasons 2015-12-04 08:11:56 +01:00
angt
4d7192667e Update configure.ac 2015-12-04 07:33:24 +01:00
angt
43f5457802 Oups 2015-12-03 21:13:24 +01:00
angt
2005068039 Wait for kx to send SIGUSR2 2015-12-03 21:11:58 +01:00
angt
9028aaea88 Update README.md 2015-12-03 20:53:43 +01:00
angt
e80eb158d8 Update README.md 2015-12-03 20:48:24 +01:00
angt
68abb63f74 Fix last commit 2015-12-03 20:10:29 +01:00
angt
c458a4d86f Dont try to poll for read when read buffer are full 2015-12-03 19:03:59 +01:00
angt
cbdba8cba3 Dont try to poll for write, use a timeout 2015-12-03 18:49:18 +01:00
angt
d787fa1dca Version 0.0.11 2015-12-03 18:10:55 +01:00
angt
b7582d0107 Set GT_TIMEOUT to 5s 2015-12-03 16:59:22 +01:00
angt
2d46958f9f Beautify usage 2015-12-02 20:51:23 +01:00
angt
9131742ff3 Add retry const option 2015-12-02 20:48:13 +01:00
angt
590bac0f89 Add trap option to use SIGUSR2 2015-12-02 17:05:51 +01:00
angt
a43f2c935d Send SIGUSR2 on successful connection 2015-12-02 16:50:34 +01:00
angt
200dd6273f Fix last commit 2015-12-02 16:08:35 +01:00
angt
2a97e94770 Version 0.0.10 2015-12-02 16:06:29 +01:00
angt
bd46acb672 Add retry (count, slope and limit) option 2015-12-02 16:05:15 +01:00
angt
723006a10d Add fake daemon mode 2015-12-02 12:04:36 +01:00
angt
da6a2a7d61 Code cleanup 2015-12-01 09:15:40 +01:00
angt
7db50de8df Version 0.0.9 2015-11-30 16:08:36 +01:00
angt
22a6b511f7 Little opt 2015-11-30 16:07:13 +01:00
angt
2f2e5e6f99 Use SIGUSR1 to show tcp_info 2015-11-29 18:10:15 +01:00
angt
3472771a6f Try to close nicely on tun error 2015-11-28 14:23:45 +01:00
angt
8989138051 Version 0.0.8 2015-11-27 14:53:18 +01:00
angt
c2f76213cc Add noquickack option 2015-11-27 14:52:52 +01:00
angt
6ed736327a Align blk.data to 16 bytes 2015-11-27 08:07:53 +01:00
angt
e20be0ad97 Keep it simple and use the right tools 2015-11-27 07:56:40 +01:00
angt
2e7355bb92 Write shutdown() should be called only one time 2015-11-27 07:44:45 +01:00
angt
8ec7238f49 Version 0.0.7 2015-11-25 15:50:38 +01:00
angt
ac10f5a4e1 Fix prio and add priority size option 2015-11-25 15:49:45 +01:00
angt
d658669a04 Beautify usage 2015-11-24 18:42:14 +01:00
angt
746d998d4e Add some useless free() 2015-11-24 13:34:29 +01:00
angt
d1c51d90d4 Version 0.0.6 2015-11-24 11:30:04 +01:00
angt
0b1303b029 Add dscp-prio option (first qos draft) 2015-11-24 11:05:16 +01:00
angt
a78089ba10 Version 0.0.5 2015-11-23 12:13:42 +01:00
angt
128aaae368 Add daemon option (only one fork) 2015-11-23 12:12:28 +01:00
angt
230c9fa26a Little fix and cleanup 2015-11-21 19:09:21 +01:00
angt
9834498d94 Avoid str_cmp() in sk_set() 2015-11-20 10:17:26 +01:00
angt
9454b5c9e1 Code cleanup 2015-11-19 23:38:13 +01:00
angt
ca3ed9ff1a Group ip packets for encryption 2015-11-19 19:07:42 +01:00
angt
836ffaad37 Increment listener backlog 2015-11-19 09:51:29 +01:00
angt
4c02e38954 Defer accept on listener 2015-11-19 09:51:29 +01:00
angt
540d0e2dff Flag is just an empty option 2015-11-19 09:51:29 +01:00
angt
0c1e3a5f09 Version 0.0.4 2015-11-18 10:39:15 +01:00
angt
4337251218 Code cleanup 2015-11-18 10:17:50 +01:00
angt
baca343fdf Simplify setsockopt() code 2015-11-18 09:24:30 +01:00
angt
c20a2a5a13 Code cleanup 2015-11-17 23:58:19 +01:00
angt
7fc368cf3c Make keepalive an option (and not a flag) 2015-11-17 23:48:55 +01:00
angt
25b62bf4c6 Simplify and generalize option_usage() 2015-11-17 23:36:03 +01:00
angt
47432ecafa Add gt_print() 2015-11-17 23:29:56 +01:00
angt
e4f2a92c5b Add ka-count, ka-idle and ka-interval options to setup keepalive 2015-11-17 22:14:35 +01:00
angt
89d2edb61b Try again to open() on EINTR 2015-11-17 21:39:56 +01:00
angt
310e499234 Version 0.0.3 2015-11-17 21:22:24 +01:00
angt
9ff87109f9 Add buffer-size option 2015-11-17 21:19:16 +01:00
angt
bfcf38f380 Try to be more robust on restart but accept some lost for now 2015-11-17 21:04:26 +01:00
angt
286f54aed4 Try to close nicely, waiting for a real proto 2015-11-17 13:10:09 +01:00
angt
6ef8ca45d7 Merge pull request #9 from jedisct1/pointer-arith
Avoid pointer arithmetic on void *
2015-11-17 07:58:19 +01:00
Frank Denis
85ddb8a8d6 Avoid pointer arithmetic on void * 2015-11-17 07:38:11 +01:00
angt
a261f1a8b1 Code cleanup 2015-11-17 07:15:59 +01:00
angt
53a55e83c4 Merge pull request #8 from jedisct1/scalarmult-check
Check crypto_scalarmult() return code
2015-11-17 06:40:13 +01:00
Frank Denis
20bdaa22e8 Check crypto_scalarmult() return code 2015-11-17 01:31:52 +01:00
angt
246f1bd7c0 Add a very simple client and server authentication 2015-11-16 16:35:43 +01:00
angt
6095cc021a Include missing uio.h in tun.c 2015-11-16 16:08:44 +01:00
angt
2ad21e9375 Include missing ip-static.h in tun.c 2015-11-16 16:05:05 +01:00
angt
21ae1f34c3 Add common.c 2015-11-16 16:00:33 +01:00
angt
a8ebefbef3 Add tun.[ch] 2015-11-16 15:44:16 +01:00
angt
14c0c2edb1 Add ip-static.h 2015-11-16 12:53:47 +01:00
angt
b8148600f2 Add keepalive option 2015-11-16 11:44:28 +01:00
angt
164c32c23c Code cleanup 2015-11-16 11:42:53 +01:00
angt
a5e415736d Merge pull request #7 from jedisct1/keepalive
Set `SO_KEEPALIVE` on the socket
2015-11-16 10:50:50 +01:00
angt
0359c21643 Merge pull request #6 from jedisct1/dd
Use /dev/urandom
2015-11-16 10:50:39 +01:00
angt
725a8e2fd0 Merge pull request #5 from jedisct1/bsd-osx
Complete support for OSX & BSD
2015-11-16 10:50:22 +01:00
Frank Denis
dae5d4a800 Set SO_KEEPALIVE on the socket so that we don't hang forever 2015-11-16 09:56:11 +01:00
Frank Denis
704e663d6a Use /dev/urandom
http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/
https://speakerdeck.com/filosottile/the-plain-simple-reality-of-entropy

Also remove the iflag=fullblock GNUism that doesn't exist on BSD and OSX
2015-11-16 02:06:21 +01:00
Frank Denis
c63885a748 Add support for the native OSX utun interface 2015-11-16 01:52:33 +01:00
Frank Denis
8530e4c378 On OSX and BSD, packets sent to the tun interface have to be prefixed
by the protocol family
2015-11-16 00:43:16 +01:00
angt
4944e76f97 Fix last commit 2015-11-15 18:38:43 +01:00
angt
5865e61fd2 Use select() in the main loop (macos is full of sh!t) 2015-11-15 18:23:29 +01:00
angt
8855ce75fc Code cleanup 2015-11-15 17:42:18 +01:00
angt
3e1809a608 Version 0.0.2 2015-11-15 16:27:03 +01:00
angt
04370f0aa0 Code cleanup 2015-11-15 10:51:28 +01:00
11 changed files with 881 additions and 373 deletions

View File

@@ -1,4 +1,13 @@
bin_PROGRAMS = glorytun
glorytun_SOURCES = src/common.h src/common-static.h src/main.c src/option.c src/option.h
glorytun_CFLAGS = $(libsodium_CFLAGS)
glorytun_LDADD = $(libsodium_LIBS)
glorytun_SOURCES = \
src/common.h \
src/common-static.h \
src/common.c \
src/ip-static.h \
src/main.c \
src/option.c \
src/option.h \
src/tun.c \
src/tun.h

View File

@@ -1,8 +1,9 @@
# glorytun
# Glorytun
Small, Simple and Stupid **TCP** VPN.
**Work In Progress:** Do not touch!
**Work In Progress:** Do not touch! This code will probably format your harddisk!
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:
@@ -16,5 +17,5 @@ To build and install the latest version:
To create and use a new secret key:
$ dd if=/dev/random iflag=fullblock of=glorytun.key bs=32 count=1
$ dd if=/dev/urandom of=glorytun.key bs=32 count=1
# glorytun keyfile glorytun.key [...]

View File

@@ -1,11 +1,12 @@
AC_PREREQ([2.65])
AC_INIT([glorytun], [0.0.1], [https://github.com/angt/glorytun/issues],
AC_INIT([glorytun], [0.0.11], [https://github.com/angt/glorytun/issues],
[glorytun], [https://github.com/angt/glorytun])
AC_CONFIG_SRCDIR([src/common.h])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([1.9 -Wall -Werror foreign tar-ustar subdir-objects])
AM_DEP_TRACK
AM_SILENT_RULES([yes])
AM_PROG_CC_C_O
AC_PROG_CC_C99
AC_USE_SYSTEM_EXTENSIONS
AC_SEARCH_LIBS([getaddrinfo], [resolv nsl])

40
src/common.c Normal file
View File

@@ -0,0 +1,40 @@
#include "common.h"
#include <stdio.h>
#include <stdarg.h>
int gt_print (const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
int ret = vfprintf(stdout, fmt, ap);
va_end(ap);
if (ret<0)
return 0;
return ret;
}
void gt_log (const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
void gt_fatal (const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
exit(EXIT_FAILURE);
}
void gt_na (const char *name)
{
gt_log("%s is not available on your platform!\n", name);
}

View File

@@ -14,7 +14,13 @@
#define PALIGN(x) ((void *)ALIGN((size_t)(x)))
#define PALIGN_DOWN(x) ((void *)ALIGN_DOWN((size_t)(x)))
#define _1_(x) (__builtin_expect((x), 1))
#define _0_(x) (__builtin_expect((x), 0))
#define _printf_(A,B) __attribute__((format(printf,A,B)))
#define _noreturn_ __attribute__((noreturn))
#define _unused_ __attribute__((unused))
#define _align_(...) __attribute__((aligned(__VA_ARGS__)))
typedef struct buffer buffer_t;
@@ -24,3 +30,8 @@ struct buffer {
uint8_t *write;
uint8_t *end;
};
int gt_print (const char *, ...) _printf_(1,2);
void gt_log (const char *, ...) _printf_(1,2);
void gt_fatal (const char *, ...) _printf_(1,2) _noreturn_;
void gt_na (const char *);

39
src/ip-static.h Normal file
View File

@@ -0,0 +1,39 @@
#pragma once
#include <stdint.h>
static inline int ip_get_version (const uint8_t *data, size_t size)
{
if (size<20) // XXX
return -1; // XXX
return data[0]>>4;
}
static inline void ip_set_size (uint8_t *data, size_t size)
{
data[2] = 0xFF&(size>>8);
data[3] = 0xFF&(size);
}
static inline ssize_t ip_get_size (const uint8_t *data, size_t size)
{
switch (ip_get_version(data, size)) {
case 4:
return (data[2]<<8)|data[3];
case -1:
return -1;
}
return 0;
}
static inline int ip_get_dscp (const uint8_t *data, size_t size)
{
switch (ip_get_version(data, size)) {
case 4:
return data[1]>>2;
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -5,18 +5,10 @@
#include "option.h"
int option_flag (void *data, _unused_ int argc, _unused_ char **argv)
{
const int one = 1;
byte_cpy(data, &one, sizeof(one));
return 0;
}
int option_str (void *data, int argc, char **argv)
{
if (argc<2 || !argv[1]) {
printf("option `%s' need a string argument\n", argv[0]);
gt_print("option `%s' need a string argument\n", argv[0]);
return -1;
}
@@ -28,7 +20,7 @@ int option_str (void *data, int argc, char **argv)
int option_long (void *data, int argc, char **argv)
{
if (argc<2 || !argv[1]) {
printf("option `%s' need an integer argument\n", argv[0]);
gt_print("option `%s' need an integer argument\n", argv[0]);
return -1;
}
@@ -37,7 +29,7 @@ int option_long (void *data, int argc, char **argv)
long val = strtol(argv[1], &end, 0);
if (errno || argv[1]==end) {
printf("argument `%s' is not a valid integer\n", argv[1]);
gt_print("argument `%s' is not a valid integer\n", argv[1]);
return -1;
}
@@ -46,8 +38,21 @@ int option_long (void *data, int argc, char **argv)
return 1;
}
int option_is_set (struct option *opts, const char *name)
{
for (int k=0; opts[k].name; k++) {
if (!str_cmp(opts[k].name, name))
return opts[k].set;
}
return 0;
}
int option_option (void *data, int argc, char **argv)
{
if (!data)
return 0;
struct option *opts = (struct option *)data;
for (int k=0; opts[k].name; k++)
@@ -61,7 +66,7 @@ int option_option (void *data, int argc, char **argv)
continue;
if (opts[k].set) {
printf("option `%s' is already set\n", opts[k].name);
gt_print("option `%s' is already set\n", opts[k].name);
return -1;
}
@@ -84,31 +89,31 @@ int option_option (void *data, int argc, char **argv)
return argc;
}
static void option_usage (struct option *opts, char *name)
static int option_usage (struct option *opts, int slen)
{
char *usage = "usage: ";
size_t slen = str_len(usage)+str_len(name);
size_t len = slen;
if (!opts)
return 0;
printf("%s%s", usage, name);
if (slen>40)
slen = 12;
int len = 0;
for (int k=0; opts[k].name; k++) {
char *arg = (opts[k].call==option_flag)?"":" ARG";
size_t inc = str_len(opts[k].name)+str_len(arg)+3;
if (len+inc>72) {
printf("\n%*s", (int)slen, "");
len = slen;
if (len>40) {
gt_print("\n%*s", slen, "");
len = 0;
}
printf(" [%s%s]", opts[k].name, arg);
len += inc;
len += gt_print(" [%s", opts[k].name);
if (opts[k].call==option_option) {
len += option_usage((struct option *)opts[k].data, slen+len);
} else {
len += gt_print(" ARG");
}
len += gt_print("]");
}
printf("\n");
return len;
}
int option (struct option *opts, int argc, char **argv)
@@ -121,8 +126,17 @@ int option (struct option *opts, int argc, char **argv)
if (ret<0 || ret+1>=argc)
return 1;
printf("option `%s' is unknown\n", argv[ret+1]);
option_usage(opts, argv[0]);
gt_print("option `%s' is unknown\n", argv[ret+1]);
int slen = gt_print("usage: %s", argv[0]);
if (slen>40) {
slen = 12;
gt_print("\n%*s", slen, "");
}
option_usage(opts, slen);
gt_print("\n");
return 1;
}

View File

@@ -7,9 +7,9 @@ struct option {
int set;
};
int option_flag (void *, int, char **);
int option_option (void *, int, char **);
int option_str (void *, int, char **);
int option_long (void *, int, char **);
int option_option (void *, int, char **);
int option (struct option *, int, char **);
int option_is_set (struct option *, const char *);
int option (struct option *, int, char **);

209
src/tun.c Normal file
View File

@@ -0,0 +1,209 @@
#include "common-static.h"
#include "ip-static.h"
#include "tun.h"
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/uio.h>
#ifdef __linux__
# include <linux/if.h>
# include <linux/if_tun.h>
#endif
#ifdef __APPLE__
# include <sys/sys_domain.h>
# include <sys/kern_control.h>
# include <net/if_utun.h>
#endif
#if defined(__APPLE__) || defined(__OpenBSD__)
# define GT_BSD_TUN 1
#endif
#ifdef __linux__
int tun_create (char *name, int multiqueue)
{
int fd = open("/dev/net/tun", O_RDWR);
if (fd<0) {
perror("open /dev/net/tun");
return -1;
}
struct ifreq ifr = {
.ifr_flags = IFF_TUN|IFF_NO_PI,
};
if (multiqueue) {
#ifdef IFF_MULTI_QUEUE
ifr.ifr_flags |= IFF_MULTI_QUEUE;
#else
gt_na("IFF_MULTI_QUEUE");
#endif
}
str_cpy(ifr.ifr_name, name, IFNAMSIZ-1);
int ret = ioctl(fd, TUNSETIFF, &ifr);
if (ret<0) {
perror("ioctl TUNSETIFF");
return -1;
}
gt_log("tun name: %s\n", ifr.ifr_name);
return fd;
}
#elif defined(__APPLE__)
int tun_create (_unused_ char *name, _unused_ int mq)
{
for (unsigned dev_id = 0; dev_id < 32; dev_id++) {
struct ctl_info ci;
byte_set(&ci, 0, sizeof(ci));
str_cpy(ci.ctl_name, UTUN_CONTROL_NAME, sizeof(ci.ctl_name)-1);
int fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
if (fd==-1)
return -1;
if (ioctl(fd, CTLIOCGINFO, &ci)==-1) {
close(fd);
continue;
}
struct sockaddr_ctl sc = {
.sc_id = ci.ctl_id,
.sc_len = sizeof(sc),
.sc_family = AF_SYSTEM,
.ss_sysaddr = AF_SYS_CONTROL,
.sc_unit = dev_id+1,
};
if (connect(fd, (struct sockaddr *)&sc, sizeof(sc))==-1) {
close(fd);
continue;
}
gt_log("tun name: /dev/utun%u\n", dev_id);
return fd;
}
return -1;
}
#else
int tun_create (_unused_ char *name, _unused_ int mq)
{
for (unsigned dev_id = 0; dev_id < 32; dev_id++) {
char dev_path[11];
snprintf(dev_path, sizeof(dev_path), "/dev/tun%u", dev_id);
int fd = open(dev_path, O_RDWR);
if (fd==-1)
continue;
gt_log("tun name: %s\n", dev_path);
return fd;
}
return -1;
}
#endif
ssize_t tun_read (int fd, void *data, size_t size)
{
if (!size)
return -1;
#ifdef GT_BSD_TUN
uint32_t family;
struct iovec iov[2] = {
{ .iov_base = &family, .iov_len = sizeof(family) },
{ .iov_base = data, .iov_len = size }
};
ssize_t ret = readv(fd, iov, 2);
#else
ssize_t ret = read(fd, data, size);
#endif
if (ret==-1) {
if (errno==EAGAIN || errno==EINTR)
return -1;
if (errno)
perror("tun read");
return 0;
}
#ifdef GT_BSD_TUN
if (ret<(ssize_t) sizeof(family))
return 0;
return ret-sizeof(family);
#else
return ret;
#endif
}
ssize_t tun_write (int fd, const void *data, size_t size)
{
if (!size)
return -1;
#ifdef GT_BSD_TUN
uint32_t family;
switch (ip_get_version(data, size)) {
case 4:
family = htonl(AF_INET);
break;
case 6:
family = htonl(AF_INET6);
break;
default:
return -1;
}
struct iovec iov[2] = {
{ .iov_base = &family, .iov_len = sizeof(family) },
{ .iov_base = (void *) data, .iov_len = size },
};
ssize_t ret = writev(fd, iov, 2);
#else
ssize_t ret = write(fd, data, size);
#endif
if (ret==-1) {
if (errno==EAGAIN || errno==EINTR)
return -1;
if (errno)
perror("tun write");
return 0;
}
#ifdef GT_BSD_TUN
if (ret<(ssize_t) sizeof(family))
return 0;
return ret-sizeof(family);
#else
return ret;
#endif
}

7
src/tun.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <unistd.h>
int tun_create (char *, int);
ssize_t tun_read (int, void *, size_t);
ssize_t tun_write (int, const void *, size_t);