diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 3 | ||||
-rw-r--r-- | src/anylike.c | 2 | ||||
-rw-r--r-- | src/echo_server.lua | 40 | ||||
-rw-r--r-- | src/l_sig_handler.c | 93 | ||||
-rw-r--r-- | src/l_sig_handler.h | 34 | ||||
-rw-r--r-- | src/main_loop.lua | 25 | ||||
-rw-r--r-- | src/sig_handler.c | 159 | ||||
-rw-r--r-- | src/sig_handler.h | 43 |
8 files changed, 378 insertions, 21 deletions
diff --git a/src/Makefile b/src/Makefile index 0fb8443..6db058b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -31,13 +31,14 @@ EXECUTABLE := anylike LUA_OBJ := $(EXECUTABLE).lc LUA_OBJ_INCLUDE := $(EXECUTABLE)_lua_bytecode.h -# sig_handler.o \ # sysexec.o \ C_OBJS := log.o \ l_log.o \ options.o \ string_list.o \ + sig_handler.o \ + l_sig_handler.o \ l_crypt.o \ anylike.o diff --git a/src/anylike.c b/src/anylike.c index 8ee0a61..a4cb272 100644 --- a/src/anylike.c +++ b/src/anylike.c @@ -37,6 +37,7 @@ #include "log.h" #include "l_log.h" #include "l_crypt.h" +#include "l_sig_handler.h" #ifndef USE_SSL_CRYPTO #include <gcrypt.h> @@ -84,6 +85,7 @@ static const luaL_Reg anylike_lualibs[] = { {LUA_STRLIBNAME, luaopen_string}, {LUA_MATHLIBNAME, luaopen_math}, {LUA_LOGLIBNAME, luaopen_log}, + {LUA_SIGNALLIBNAME, luaopen_signal}, {LUA_CRYPTLIBNAME, luaopen_crypt}, {NULL, NULL} }; diff --git a/src/echo_server.lua b/src/echo_server.lua index 8ebfcf0..2a40754 100644 --- a/src/echo_server.lua +++ b/src/echo_server.lua @@ -25,44 +25,46 @@ socket = require("socket") -function echo_server() +function echo_server_init() local host, port = "localhost", 4500 local ip, err = socket.dns.toip(host) if(ip == nil) then log.printf("ERROR", "can't resolve %s: %s", host, err) - return -1 + return nil end local udp, err = socket.udp() if(udp == nil) then log.printf("ERROR", "can't create udp socket") - return -1 + return nil end local ret, err = udp:setsockname(ip, port) if(ret == nil) then log.printf("ERROR", "setsockname(%s,%s) failed: %s", ip, port, err) - return -1 + return nil end log.printf("NOTICE", "echo server listening on %s:%s", ip, port); - - while true do - local dgrm, from_ip, from_port = udp:receivefrom() - if(dgrm == nil) then - log.printf("ERROR", "receivefrom(%s,%s) failed: %s", ip, port, from_ip) - return -1 - end + + return udp +end + +function echo_server_recv(udp) + local dgrm, from_ip, from_port = udp:receivefrom() + if(dgrm == nil) then + log.printf("ERROR", "receivefrom(%s,%s) failed: %s", ip, port, from_ip) + return -1 + end - local ret, err = udp:sendto(dgrm, from_ip, from_port) - if(ret == nil) then - log.printf("ERROR", "sendto(%s,%s) failed: %s", ip, port, err) - return -1 - end + local ret, err = udp:sendto(dgrm, from_ip, from_port) + if(ret == nil) then + log.printf("ERROR", "sendto(%s,%s) failed: %s", ip, port, err) + return -1 + end - if(string.gsub(dgrm, "^(%w+)%s*%c$", "%1") == "quit") then - return 0 - end + if(string.gsub(dgrm, "^(%w+)%s*%c$", "%1") == "quit") then + return 2 end return 0 diff --git a/src/l_sig_handler.c b/src/l_sig_handler.c new file mode 100644 index 0000000..ea2501a --- /dev/null +++ b/src/l_sig_handler.c @@ -0,0 +1,93 @@ +/* + * anylike + * + * anylike is a ... + * + * + * Copyright (C) 2009-2010 Markus Grueneis <gimpf@anylike.org> + * Christian Pointner <equinox@anylike.org> + * + * This file is part of anylike. + * + * anylike is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * anylike is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with anylike. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <lua.h> +#include <lauxlib.h> + +#include "sig_handler.h" + +#include "l_sig_handler.h" + +static int l_signal_getfd(lua_State *L) +{ + if(!lua_istable(L, -1)) + luaL_error(L, "can't retreive signal fd"); + + lua_pushliteral(L, "fd"); + lua_gettable(L, -2); + return 1; +} + +static int l_signal_dirty(lua_State *L) +{ + lua_pushboolean(L, 0); + return 1; +} + +static int l_signal_init(lua_State *L) +{ + int sig_fd = signal_init(); + if(sig_fd < 0) + luaL_error(L, "error at signal init"); + + lua_newtable(L); + lua_pushliteral(L, "fd"); + lua_pushinteger(L, sig_fd); + lua_settable(L, -3); + lua_pushliteral(L, "getfd"); + lua_pushcfunction(L, l_signal_getfd); + lua_settable(L, -3); + lua_pushliteral(L, "dirty"); + lua_pushcfunction(L, l_signal_dirty); + lua_settable(L, -3); + return 1; +} + +static int l_signal_stop(lua_State *L) +{ + signal_stop(); + return 0; +} + +static int l_signal_handle(lua_State *L) +{ + int ret = signal_handle(); + lua_pushinteger(L, ret); + return 1; +} + +static const struct luaL_reg signal_funcs [] = { + { "init", l_signal_init }, + { "stop", l_signal_stop }, + { "handle", l_signal_handle }, + { NULL, NULL } +}; + + +LUALIB_API int luaopen_signal(lua_State *L) +{ + luaL_register(L, LUA_SIGNALLIBNAME, signal_funcs); + return 1; +} diff --git a/src/l_sig_handler.h b/src/l_sig_handler.h new file mode 100644 index 0000000..dfeb39d --- /dev/null +++ b/src/l_sig_handler.h @@ -0,0 +1,34 @@ +/* + * anylike + * + * anylike is a ... + * + * + * Copyright (C) 2009-2010 Markus Grueneis <gimpf@anylike.org> + * Christian Pointner <equinox@anylike.org> + * + * This file is part of anylike. + * + * anylike is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * anylike is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with anylike. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ANYLIKE_l_signal_handler_h_INCLUDED +#define ANYLIKE_l_signal_handler_h_INCLUDED + +#include <lua.h> + +#define LUA_SIGNALLIBNAME "signal" +LUALIB_API int luaopen_signal(lua_State *L); + +#endif diff --git a/src/main_loop.lua b/src/main_loop.lua index 8124298..9f32d0b 100644 --- a/src/main_loop.lua +++ b/src/main_loop.lua @@ -23,8 +23,31 @@ -- along with anylike. If not, see <http://www.gnu.org/licenses/>. -- +socket = require("socket") + function main_loop(opt) log.printf("NOTICE", "main_loop started") + local sig = signal.init() + + local sock = echo_server_init() + if(sock == nil) then return -1 end + + local ret = 0 + while ret == 0 do + local readable, _, err = socket.select({ sig , sock }, nil) + for _, input in ipairs(readable) do + if(input == sig) then + ret = signal.handle() + else + if(input == sock) then + ret = echo_server_recv(sock) + end + end + end + end + + if(ret == 2) then ret = 0 end - return echo_server() + signal.stop() + return ret end diff --git a/src/sig_handler.c b/src/sig_handler.c new file mode 100644 index 0000000..ca2e18f --- /dev/null +++ b/src/sig_handler.c @@ -0,0 +1,159 @@ +/* + * uAnytun + * + * uAnytun is a tiny implementation of SATP. Unlike Anytun which is a full + * featured implementation uAnytun has no support for multiple connections + * or synchronisation. It is a small single threaded implementation intended + * to act as a client on small platforms. + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Christian Pointner <equinox@anytun.org> + * + * This file is part of uAnytun. + * + * uAnytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * uAnytun is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with uAnytun. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "datatypes.h" + +#include "log.h" +#include <signal.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/select.h> +#include <errno.h> + +#include "sig_handler.h" + +#include <stdio.h> + + +static int sig_pipe_fds[2]; + + +static void sig_handler(int sig) +{ + sigset_t set; + int ret = read(sig_pipe_fds[0], &set, sizeof(sigset_t)); + if(ret != sizeof(sigset_t)) + sigemptyset(&set); + + sigaddset(&set, sig); + ret = write(sig_pipe_fds[1], &set, sizeof(sigset_t)); +} + + +int signal_init() +{ + if(pipe(sig_pipe_fds)) { + log_printf(ERROR, "signal handling init failed (pipe error: %s)", strerror(errno)); + return -1; + } + + int i; + for(i=0; i<2; ++i) { + int fd_flags = fcntl(sig_pipe_fds[i], F_GETFL); + if(fd_flags == -1) { + log_printf(ERROR, "signal handling init failed (pipe fd[%d] read flags error: %s)", i, strerror(errno)); + return -1; + } + if(fcntl(sig_pipe_fds[i], F_SETFL, fd_flags | O_NONBLOCK) == -1){ + log_printf(ERROR, "signal handling init failed (pipe fd[%d] write flags error: %s)", i, strerror(errno)); + return -1; + } + } + + struct sigaction act; + act.sa_handler = sig_handler; + sigfillset(&act.sa_mask); + act.sa_flags = 0; + + if((sigaction(SIGINT, &act, NULL) < 0) || + (sigaction(SIGQUIT, &act, NULL) < 0) || + (sigaction(SIGTERM, &act, NULL) < 0) || + (sigaction(SIGHUP, &act, NULL) < 0) || + (sigaction(SIGUSR1, &act, NULL) < 0) || + (sigaction(SIGUSR2, &act, NULL) < 0)) { + + log_printf(ERROR, "signal handling init failed (sigaction error: %s)", strerror(errno)); + close(sig_pipe_fds[0]); + close(sig_pipe_fds[1]); + } + + return sig_pipe_fds[0]; +} + +int signal_handle() +{ + sigset_t set, oldset, tmpset; + + sigemptyset(&tmpset); + sigaddset(&tmpset, SIGINT); + sigaddset(&tmpset, SIGQUIT); + sigaddset(&tmpset, SIGTERM); + sigaddset(&tmpset, SIGHUP); + sigaddset(&tmpset, SIGUSR1); + sigaddset(&tmpset, SIGUSR2); + sigprocmask(SIG_BLOCK, &tmpset, &oldset); + + int ret = read(sig_pipe_fds[0], &set, sizeof(sigset_t)); + if(ret != sizeof(sigset_t)) + sigemptyset(&set); + + int return_value = 0; + int sig; + for(sig=1; sig < NSIG; ++sig) { + if(sigismember(&set, sig)) { + switch(sig) { + case SIGINT: log_printf(NOTICE, "SIG-Int caught, exitting"); return_value = 1; break; + case SIGQUIT: log_printf(NOTICE, "SIG-Quit caught, exitting"); return_value = 1; break; + case SIGTERM: log_printf(NOTICE, "SIG-Term caught, exitting"); return_value = 1; break; + case SIGHUP: log_printf(NOTICE, "SIG-Hup caught"); break; + case SIGUSR1: log_printf(NOTICE, "SIG-Usr1 caught"); break; + case SIGUSR2: log_printf(NOTICE, "SIG-Usr2 caught"); break; + default: log_printf(WARNING, "unknown signal %d caught, ignoring", sig); break; + } + sigdelset(&set, sig); + } + } + + sigprocmask(SIG_SETMASK, &oldset, NULL); + return return_value; +} + +void signal_stop() +{ + struct sigaction act; + act.sa_handler = SIG_DFL; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + + sigaction(SIGINT, &act, NULL); + sigaction(SIGQUIT, &act, NULL); + sigaction(SIGTERM, &act, NULL); + sigaction(SIGHUP, &act, NULL); + sigaction(SIGUSR1, &act, NULL); + sigaction(SIGUSR2, &act, NULL); + + close(sig_pipe_fds[0]); + close(sig_pipe_fds[1]); +} diff --git a/src/sig_handler.h b/src/sig_handler.h new file mode 100644 index 0000000..1995e1a --- /dev/null +++ b/src/sig_handler.h @@ -0,0 +1,43 @@ +/* + * uAnytun + * + * uAnytun is a tiny implementation of SATP. Unlike Anytun which is a full + * featured implementation uAnytun has no support for multiple connections + * or synchronisation. It is a small single threaded implementation intended + * to act as a client on small platforms. + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Christian Pointner <equinox@anytun.org> + * + * This file is part of uAnytun. + * + * uAnytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * uAnytun is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with uAnytun. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef UANYTUN_sig_handler_h_INCLUDED +#define UANYTUN_sig_handler_h_INCLUDED + +int signal_init(); +int signal_handle(); +void signal_stop(); + +#endif |