Compare commits

...

69 Commits

Author SHA1 Message Date
angt
b0d5007bfb Restore STARTED and STOPPED states 2016-03-24 14:45:15 +00:00
angt
d2046eb00b Revert "Add branch name in version"
This reverts commit 03cd87df1c.
2016-03-09 11:42:51 +00:00
angt
d04acc9c0f Update mud 2016-03-09 10:59:52 +00:00
angt
03cd87df1c Add branch name in version 2016-03-09 10:20:01 +00:00
angt
8e8ad7178d Update mud 2016-03-04 11:32:42 +00:00
angt
0e26b4def7 Update mud 2016-03-04 11:20:15 +00:00
angt
f800985766 Update mud 2016-03-04 11:01:43 +00:00
angt
7b88c28a45 Update mud 2016-03-03 10:49:28 +00:00
angt
194dfe17d3 Update mud 2016-03-02 12:59:33 +00:00
angt
664160e0cc Add bind-port option 2016-03-01 15:11:16 +00:00
angt
1dd760e382 Code cleanup 2016-03-01 08:13:05 +00:00
angt
05219b81f7 Update README.md 2016-02-29 16:14:08 +00:00
angt
0bb7e4f1d0 Update mud 2016-02-29 15:35:57 +00:00
angt
a7fbf806fb Use a list to setup mud_bind() 2016-02-29 15:28:37 +00:00
angt
e750c46665 Update mud 2016-02-25 15:22:47 +00:00
angt
935111cfea Fix Makefile.am 2016-02-04 11:31:02 +01:00
angt
c4b2512df4 Add .gitmodules 2016-02-04 10:44:53 +01:00
angt
27970e24fb Import and use mud 2016-02-04 10:39:36 +01:00
angt
acc3ee3461 Encrypt only one packet at a time 2016-01-26 12:18:00 +01:00
angt
eefa7722c5 Use timeout in connect() too 2016-01-21 16:22:31 +01:00
angt
17547f555d Add SECRETKEY state 2016-01-18 18:07:35 +01:00
angt
ec9c59ce69 Code cleanup 2016-01-18 18:00:41 +01:00
angt
679927a684 Show device name in INITIALIZED state 2016-01-18 17:58:20 +01:00
angt
2999faf5d7 Move up state_init() 2016-01-18 17:26:42 +01:00
angt
219384b7e5 Remove the old school daemon option 2016-01-18 16:09:29 +01:00
angt
3649e46b03 Remove the absolute path restriction on statefile 2016-01-18 16:02:29 +01:00
angt
88f314bc75 Add state.[ch] 2016-01-18 15:59:18 +01:00
angt
e2b3dc1b46 Use only v[0-9].* tags to get VERSION 2016-01-17 10:56:55 +01:00
angt
1815ea519f Create a tcp_entry only on ACK 2016-01-17 10:18:39 +01:00
angt
33356d5d35 Don't work too much 2016-01-17 09:40:56 +01:00
angt
4a5d07ec45 Merge pull request #11 from jedisct1/notag
Cope with branches that don't have tags
2016-01-16 16:16:05 +01:00
Frank Denis
a50882e1ac Cope with branches that don't have tags
`version.sh` used to return only the hash of the last commit, causing
VERSION_MAJOR to possibly contain non-numeric junk.
2016-01-16 15:37:42 +01:00
angt
b2cb8ebcbe The minimum value for buffer-size option is GT_PKT_MAX 2016-01-15 17:02:11 +01:00
angt
6fd6cf8c4a Merge pull request #10 from jedisct1/socket
Include <sys/socket.h> for AF_INET/AF_INET6 definitions
2016-01-14 17:14:56 +01:00
Frank Denis
f0fc2751e5 Include <sys/socket.h> for AF_INET/AF_INET6 definitions
Required on OpenBSD
2016-01-14 17:11:27 +01:00
angt
81cab007d0 Resend packet on partial tun_write() 2016-01-14 10:25:37 +01:00
angt
606396839f Don't update sa->base with old acks 2016-01-14 09:27:15 +01:00
angt
a8e37bafb9 Use realloc(): easier, better, faster, stronger 2016-01-13 16:19:58 +01:00
angt
87a38012cd Don't forget to free() seq_elem 2016-01-13 16:16:05 +01:00
angt
f04816e9a5 Try to detect TCP retransmission 2016-01-12 18:07:58 +01:00
angt
7107d036b1 Code cleanup 2016-01-07 08:30:21 +01:00
angt
30502e05ec Print state info in stdout if no statefile 2016-01-06 18:41:39 +01:00
angt
905673ecec Add timeout option 2016-01-06 18:33:59 +01:00
angt
cfbb77c710 Code cleanup 2016-01-06 17:57:12 +01:00
angt
13dcdc5afb Reduce GT_BUFFER_SIZE 2016-01-06 16:03:42 +01:00
angt
56ec81bf92 Fix last commit 2016-01-06 12:15:28 +01:00
angt
f1024381e0 Remove old code from qos 2016-01-06 11:29:13 +01:00
angt
3f3b21f08d Update Makefile.am 2016-01-05 14:16:30 +01:00
angt
40dd5ce18a Code cleanup 2016-01-05 14:07:18 +01:00
angt
5efb379251 Remove byte_*() as we don't use freestanding anymore 2016-01-05 12:26:38 +01:00
angt
2eb6521f9c Add a simple tcp tracker in debug mode 2016-01-05 08:24:03 +01:00
angt
bfd81e9666 Code cleanup 2016-01-04 20:07:11 +01:00
angt
8fa2322314 Add VERSION in the tarball 2016-01-01 12:32:20 +01:00
angt
8982f27220 Update LICENSE 2016-01-01 11:47:17 +01:00
angt
a5f97fcc8c States need EOL 2016-01-01 11:00:29 +01:00
angt
35a9bf27df Add state INITIALIZED 2015-12-31 16:07:36 +01:00
angt
ba0af8cc20 Define VERSION_MAJOR and use it in handshake 2015-12-29 18:31:23 +01:00
angt
ec85be5c6a Code cleanup 2015-12-29 12:59:55 +01:00
angt
fe989851ab Print more debug info 2015-12-29 12:58:39 +01:00
angt
46842dd200 Write state after the close() 2015-12-28 07:18:00 +01:00
angt
e5eb30598d Code cleanup 2015-12-24 17:38:08 +01:00
angt
c81ad0a7c6 One more time 2015-12-24 17:35:01 +01:00
angt
97641d6dda Reserve exclam for very bad message 2015-12-24 17:32:32 +01:00
angt
e48dac775c The statefile option needs an absolute path and a fifo 2015-12-24 17:29:41 +01:00
angt
6282f36ac7 Add statefile option 2015-12-24 16:53:50 +01:00
angt
cf022af4a9 Simplify the db by merging size and mask 2015-12-24 13:13:43 +01:00
angt
597c586657 Don't free data in db_remove() 2015-12-23 22:26:53 +01:00
angt
fc7f9aa0c8 Add a very simple low cost database 2015-12-23 17:11:20 +01:00
angt
7492f977b6 Define a simple proto 2015-12-21 12:34:24 +01:00
22 changed files with 601 additions and 1092 deletions

3
.gitmodules vendored Normal file
View File

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

View File

@@ -1,4 +1,4 @@
Copyright (c) 2015, angt Copyright (c) 2015-2016, angt
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -6,17 +6,28 @@ glorytun_CFLAGS = $(libsodium_CFLAGS)
glorytun_LDADD = $(libsodium_LIBS) glorytun_LDADD = $(libsodium_LIBS)
glorytun_SOURCES = \ glorytun_SOURCES = \
src/common.h \ src/common.h \
src/common-static.h \
src/common.c \ src/common.c \
src/ip-static.h \ src/buffer.h \
src/ip.h \
src/str.h \
src/main.c \ src/main.c \
src/option.c \ src/option.c \
src/option.h \ src/option.h \
src/tun.c \ src/tun.c \
src/tun.h src/tun.h \
src/db.c \
src/db.h \
src/state.c \
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 \
VERSION \
autogen.sh \ autogen.sh \
version.sh version.sh

View File

@@ -1,6 +1,6 @@
# Glorytun # Glorytun
Small, Simple and Stupid TCP VPN. Small, Simple and Stupid VPN over [mud](https://github.com/angt/mud).
#### Work In Progress #### Work In Progress
@@ -13,7 +13,7 @@ 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 $ git clone https://github.com/angt/glorytun --recursive --branch mud
$ cd glorytun $ cd glorytun
$ ./autogen.sh $ ./autogen.sh
$ ./configure $ ./configure

View File

@@ -4,6 +4,7 @@ AC_INIT([glorytun],
[https://github.com/angt/glorytun/issues], [https://github.com/angt/glorytun/issues],
[glorytun], [glorytun],
[https://github.com/angt/glorytun]) [https://github.com/angt/glorytun])
AC_DEFINE_UNQUOTED([VERSION_MAJOR], [m4_esyscmd([./version.sh major])])
AC_CONFIG_SRCDIR([src/common.h]) AC_CONFIG_SRCDIR([src/common.h])
AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])

1
mud Submodule

Submodule mud added at 1b58401095

66
src/buffer.h Normal file
View File

@@ -0,0 +1,66 @@
#pragma once
#include "common.h"
typedef struct buffer buffer_t;
struct buffer {
uint8_t *data;
uint8_t *read;
uint8_t *write;
uint8_t *end;
};
static inline void buffer_setup (buffer_t *buffer, void *data, size_t size)
{
if (!data)
data = malloc(ALIGN(size));
buffer->data = data;
buffer->read = data;
buffer->write = data;
buffer->end = data;
buffer->end += size;
}
static inline void buffer_format (buffer_t *buffer)
{
buffer->write = buffer->data;
buffer->read = buffer->data;
}
_pure_
static inline size_t buffer_size (buffer_t *buffer)
{
return buffer->end-buffer->data;
}
_pure_
static inline size_t buffer_write_size (buffer_t *buffer)
{
return buffer->end-buffer->write;
}
_pure_
static inline size_t buffer_read_size (buffer_t *buffer)
{
return buffer->write-buffer->read;
}
static inline void buffer_shift (buffer_t *buffer)
{
if (buffer->read==buffer->data)
return;
if (buffer->read==buffer->write) {
buffer_format(buffer);
return;
}
const size_t size = buffer_read_size(buffer);
memmove(buffer->data, buffer->read, size);
buffer->read = buffer->data;
buffer->write = buffer->data+size;
}

View File

@@ -1,153 +0,0 @@
#pragma once
#include "common.h"
#include <unistd.h>
#include <errno.h>
static inline void byte_set (void *dst, const char value, size_t size)
{
if (!dst)
return;
char *restrict d = dst;
while (size--)
*d++ = value;
}
static inline void byte_cpy (void *dst, const void *src, size_t size)
{
if (!dst)
return;
char *restrict d = dst;
const char *restrict s = src;
while (size--)
*d++ = *s++;
}
static inline size_t str_cpy (char *restrict dst, const char *restrict src, size_t len)
{
if (!dst || !src)
return 0;
size_t i;
for (i=0; i<len && src[i]; i++)
dst[i] = src[i];
dst[i] = 0;
return i;
}
_pure_
static inline int str_empty (const char *restrict str)
{
return !str || !str[0];
}
_pure_
static inline int str_cmp (const char *restrict sa, const char *restrict sb)
{
if (!sa || !sb)
return 1;
while (*sa==*sb++)
if (!*sa++)
return 0;
return 1;
}
_pure_
static inline size_t str_len (const char *restrict str)
{
if (!str)
return 0;
size_t i = 0;
while (str[i])
i++;
return i;
}
static inline char *str_cat (const char *const strs[], size_t count)
{
size_t size = 1;
for (size_t i=0; i<count; i++)
size += str_len(strs[i]);
char *str = malloc(size);
if (!str)
return NULL;
char *p = str;
for (size_t i=0; i<count; i++) {
size_t len = str_len(strs[i]);
byte_cpy(p, strs[i], len);
p += len;
}
p[0] = 0;
return str;
}
static inline void buffer_setup (buffer_t *buffer, void *data, size_t size)
{
if (!data)
data = malloc(ALIGN(size));
buffer->data = data;
buffer->read = data;
buffer->write = data;
buffer->end = data;
buffer->end += size;
}
static inline void buffer_format (buffer_t *buffer)
{
buffer->write = buffer->data;
buffer->read = buffer->data;
}
_pure_
static inline size_t buffer_size (buffer_t *buffer)
{
return buffer->end-buffer->data;
}
_pure_
static inline size_t buffer_write_size (buffer_t *buffer)
{
return buffer->end-buffer->write;
}
_pure_
static inline size_t buffer_read_size (buffer_t *buffer)
{
return buffer->write-buffer->read;
}
static inline void buffer_shift (buffer_t *buffer)
{
if (buffer->read==buffer->write) {
buffer_format(buffer);
} else {
const uint8_t *src = PALIGN_DOWN(buffer->read);
const size_t size = ALIGN(buffer->write-src);
if (buffer->data+size<src) {
byte_cpy(buffer->data, src, size);
buffer->read -= src-buffer->data;
buffer->write -= src-buffer->data;
}
}
}

View File

@@ -36,7 +36,7 @@ void gt_fatal (const char *fmt, ...)
void gt_na (const char *name) void 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 gt_tohex (char *dst, size_t dst_size, const uint8_t *src, size_t src_size) int gt_tohex (char *dst, size_t dst_size, const uint8_t *src, size_t src_size)

View File

@@ -2,6 +2,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#define COUNT(x) (sizeof(x)/sizeof(x[0])) #define COUNT(x) (sizeof(x)/sizeof(x[0]))
@@ -17,6 +20,8 @@
#define _1_(x) (__builtin_expect((x), 1)) #define _1_(x) (__builtin_expect((x), 1))
#define _0_(x) (__builtin_expect((x), 0)) #define _0_(x) (__builtin_expect((x), 0))
#define CLZ(x) (__builtin_clz(x))
#define _printf_(A,B) __attribute__ ((format(printf,A,B))) #define _printf_(A,B) __attribute__ ((format(printf,A,B)))
#define _noreturn_ __attribute__ ((noreturn)) #define _noreturn_ __attribute__ ((noreturn))
#define _unused_ __attribute__ ((unused)) #define _unused_ __attribute__ ((unused))
@@ -24,15 +29,6 @@
#define _const_ __attribute__ ((const)) #define _const_ __attribute__ ((const))
#define _align_(...) __attribute__ ((aligned(__VA_ARGS__))) #define _align_(...) __attribute__ ((aligned(__VA_ARGS__)))
typedef struct buffer buffer_t;
struct buffer {
uint8_t *data;
uint8_t *read;
uint8_t *write;
uint8_t *end;
};
int gt_print (const char *, ...) _printf_(1,2); int gt_print (const char *, ...) _printf_(1,2);
void gt_log (const char *, ...) _printf_(1,2); void gt_log (const char *, ...) _printf_(1,2);
void gt_fatal (const char *, ...) _printf_(1,2) _noreturn_; void gt_fatal (const char *, ...) _printf_(1,2) _noreturn_;

155
src/db.c Normal file
View File

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

7
src/db.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <stdint.h>
uint8_t *db_search (uint8_t **, uint8_t *);
uint8_t *db_insert (uint8_t **, uint8_t *);
uint8_t *db_remove (uint8_t **, uint8_t *);

View File

@@ -1,57 +0,0 @@
#pragma once
#include <stdint.h>
_pure_
static inline int ip_get_version (const uint8_t *data, size_t size)
{
if (size<20) // XXX
return -1; // XXX
return data[0]>>4;
}
_pure_
static inline ssize_t ip_get_size (const int ip_version, const uint8_t *data, size_t size)
{
switch (ip_version) {
case 4:
return ((data[2]<<8)|data[3]);
case 6:
return ((data[4]<<8)|data[5])+40;
case -1:
return -1;
}
return 0;
}
_pure_
static inline ssize_t ip_get_proto (const int ip_version, const uint8_t *data, size_t size)
{
switch (ip_version) {
case 4:
return data[9];
case 6:
return data[6];
case -1:
return -1;
}
return 0;
}
_pure_
static inline ssize_t ip_get_hdr_size (const int ip_version, const uint8_t *data, size_t size)
{
switch (ip_version) {
case 4:
return (data[0]&0xF)<<2;
case 6:
return 40;
case -1:
return -1;
}
return 0;
}

39
src/ip.h Normal file
View File

@@ -0,0 +1,39 @@
#pragma once
#include <stdint.h>
struct ip_common {
uint8_t version;
uint8_t proto;
uint8_t hdr_size;
uint16_t size;
};
_pure_
static inline uint8_t ip_get_version (const uint8_t *data, size_t size)
{
if (size<20)
return 0;
return data[0]>>4;
}
static inline int ip_get_common (struct ip_common *ic, const uint8_t *data, size_t size)
{
ic->version = ip_get_version(data, size);
switch (ic->version) {
case 4:
ic->proto = data[9];
ic->hdr_size = (data[0]&0xF)<<2;
ic->size = ((data[2]<<8)|data[3]);
return 0;
case 6:
ic->proto = data[6];
ic->hdr_size = 40;
ic->size = ((data[4]<<8)|data[5])+40;
return 0;
}
return -1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,25 +1,23 @@
#include "common-static.h" #include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include "option.h" #include "option.h"
#include "str.h"
int option_str (void *data, int argc, char **argv) int option_str (void *data, int argc, char **argv)
{ {
if (argc<2 || !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;
} }
byte_cpy(data, &argv[1], sizeof(argv[1])); memcpy(data, &argv[1], sizeof(argv[1]));
return 1; return 1;
} }
int option_long (void *data, int argc, char **argv) int option_long (void *data, int argc, char **argv)
{ {
if (argc<2 || !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;
} }
@@ -33,7 +31,7 @@ int option_long (void *data, int argc, char **argv)
return -1; return -1;
} }
byte_cpy(data, &val, sizeof(val)); memcpy(data, &val, sizeof(val));
return 1; return 1;
} }

61
src/state.c Normal file
View File

@@ -0,0 +1,61 @@
#include "common.h"
#include "state.h"
#include "str.h"
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
static int state_fd = -1;
int state_init (const char *filename)
{
if (str_empty(filename))
return 0;
state_fd = open(filename, O_WRONLY);
if (state_fd==-1) {
if (errno!=EINTR)
perror("open");
return -1;
}
struct stat st = {0};
if (fstat(state_fd, &st)==-1) {
perror("fstat");
close(state_fd);
state_fd = -1;
return -1;
}
if (!S_ISFIFO(st.st_mode)) {
gt_log("`%s' is not a fifo\n", filename);
close(state_fd);
state_fd = -1;
return -1;
}
return 0;
}
void state (const char *state, const char *info)
{
if (str_empty(state))
return;
const char *strs[] = { state, " ", info, "\n" };
char *str = str_cat(strs, COUNT(strs));
if (!str)
return;
if (state_fd==-1) {
gt_print("%s", str);
} else {
if (write(state_fd, str, str_len(str))==-1 && errno!=EINTR)
perror("write");
}
}

4
src/state.h Normal file
View File

@@ -0,0 +1,4 @@
#pragma once
int state_init (const char *);
void state (const char *, const char *);

73
src/str.h Normal file
View File

@@ -0,0 +1,73 @@
#pragma once
#include "common.h"
static inline size_t str_cpy (char *restrict dst, const char *restrict src, size_t len)
{
if (!dst || !src)
return 0;
size_t i;
for (i=0; i<len && src[i]; i++)
dst[i] = src[i];
dst[i] = 0;
return i;
}
_pure_
static inline int str_empty (const char *restrict str)
{
return !str || !str[0];
}
_pure_
static inline size_t str_cmp (const char *restrict sa, const char *restrict sb)
{
if (!sa || !sb)
return 1;
size_t i = 0;
while (sa[i]==sb[i])
if (!sa[i++])
return 0;
return i+1;
}
_pure_
static inline size_t str_len (const char *restrict str)
{
if (!str)
return 0;
return strlen(str);
}
static inline char *str_cat (const char **strs, size_t count)
{
size_t size = 1;
for (size_t i=0; i<count; i++)
size += str_len(strs[i]);
char *str = malloc(size);
if (!str)
return NULL;
char *p = str;
for (size_t i=0; i<count; i++) {
size_t len = str_len(strs[i]);
memcpy(p, strs[i], len);
p += len;
}
p[0] = 0;
return str;
}

View File

@@ -1,7 +1,8 @@
#include "common-static.h" #include "common.h"
#include "ip-static.h"
#include "tun.h" #include "tun.h"
#include "str.h"
#include "ip.h"
#include <stdio.h> #include <stdio.h>
#include <fcntl.h> #include <fcntl.h>
@@ -36,7 +37,7 @@ static int tun_create_by_id (char *name, size_t size, unsigned id, _unused_ int
struct ctl_info ci; struct ctl_info ci;
byte_set(&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)) {
@@ -130,9 +131,9 @@ static int tun_create_by_id (char *name, size_t size, unsigned id, int mq)
#endif #endif
int tun_create (char *dev_name, int mq) int tun_create (char *dev_name, char **ret_name, int mq)
{ {
char name[64]; char name[64] = {0};
int fd = -1; int fd = -1;
#ifndef IFF_MULTI_QUEUE #ifndef IFF_MULTI_QUEUE
@@ -147,8 +148,8 @@ int tun_create (char *dev_name, int mq)
fd = tun_create_by_name(name, sizeof(name), dev_name, mq); fd = tun_create_by_name(name, sizeof(name), dev_name, mq);
} }
if (fd!=-1) if (fd!=-1 && ret_name)
gt_print("tun name: %s\n", name); *ret_name = strdup(name);
return fd; return fd;
} }

View File

@@ -2,6 +2,6 @@
#include <unistd.h> #include <unistd.h>
int tun_create (char *, int); 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);

View File

@@ -1,9 +1,13 @@
#!/bin/sh #!/bin/sh
[ -z "${VERSION}" ] && VERSION=`git describe --tags --always 2>/dev/null` \ [ -z "${VERSION}" ] && VERSION=`git describe --tags --match='v[0-9].*' 2>/dev/null` \
&& VERSION=${VERSION#v} && VERSION=${VERSION#v}
[ -z "${VERSION}" ] && VERSION=`basename \`pwd\`` \ [ -z "${VERSION}" ] && VERSION=`cat VERSION 2>/dev/null`
&& VERSION=${VERSION#*-}
printf ${VERSION} [ -z "${VERSION}" ] && VERSION=0.0.0
[ "$1" = "major" ] && printf ${VERSION%%.*} \
&& exit 0
printf ${VERSION} | tee VERSION