summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@anylike.org>2009-12-27 21:40:41 +0000
committerChristian Pointner <equinox@anylike.org>2009-12-27 21:40:41 +0000
commit4b23ff1cbdadc9e9900f15d4fa75831dca9b820e (patch)
tree42a097689fa21f7cafd27b84217acaf82d4253df
parentadded tools directory (diff)
added signal handler and initial main loop
-rw-r--r--src/Makefile3
-rw-r--r--src/anylike.c2
-rw-r--r--src/echo_server.lua40
-rw-r--r--src/l_sig_handler.c93
-rw-r--r--src/l_sig_handler.h34
-rw-r--r--src/main_loop.lua25
-rw-r--r--src/sig_handler.c159
-rw-r--r--src/sig_handler.h43
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