From 729f0bb2677eb1f22ecff2284e987e99212541a3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Philipp=20T=C3=B6lke?= Date: Tue, 20 Jul 2010 05:45:25 +0000 Subject: [PATCH] start the helper from the daemon, end it correctly --- src/vpn/gnunet-daemon-vpn.c | 47 +++++++++++++++++++++++++++++++------ src/vpn/gnunet-vpn-helper.c | 43 ++++++++++++++++++++++++++------- 2 files changed, 75 insertions(+), 15 deletions(-) diff --git a/src/vpn/gnunet-daemon-vpn.c b/src/vpn/gnunet-daemon-vpn.c index 2b304faf0..23b50c699 100644 --- a/src/vpn/gnunet-daemon-vpn.c +++ b/src/vpn/gnunet-daemon-vpn.c @@ -26,6 +26,7 @@ #include "platform.h" #include "gnunet_getopt_lib.h" #include "gnunet_program_lib.h" +#include "gnunet_os_lib.h" /* #include "gnunet_template_service.h" */ /** @@ -33,6 +34,24 @@ */ static int ret; +struct vpn_cls { + struct GNUNET_DISK_PipeHandle* helper_in; + struct GNUNET_DISK_PipeHandle* helper_out; + + pid_t helper_pid; +}; + +static void cleanup(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tskctx) { + struct vpn_cls* mycls = (struct vpn_cls*) cls; + if (tskctx->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) { + PLIBC_KILL(mycls->helper_pid, SIGTERM); + GNUNET_OS_process_wait(mycls->helper_pid); + } +} + +static void helper_read(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tsdkctx) { +} + /** * Main function that will be run by the scheduler. * @@ -44,12 +63,23 @@ static int ret; */ static void run (void *cls, - struct GNUNET_SCHEDULER_Handle *sched, - char *const *args, - const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - /* main code here */ + struct GNUNET_SCHEDULER_Handle *sched, + char *const *args, + const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) { + + struct vpn_cls* mycls = (struct vpn_cls*) cls; + + GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls); + + mycls->helper_in = GNUNET_DISK_pipe(1); + mycls->helper_out = GNUNET_DISK_pipe(1); + + mycls->helper_pid = GNUNET_OS_start_process(mycls->helper_in, mycls->helper_out, "gnunet-vpn-helper", "gnunet-vpn-helper", NULL); + + const struct GNUNET_DISK_FileHandle* fh = GNUNET_DISK_pipe_handle (mycls->helper_out, GNUNET_DISK_PIPE_END_READ); + + GNUNET_SCHEDULER_add_read_file (sched, GNUNET_TIME_UNIT_FOREVER_REL, fh, &helper_read, mycls); } @@ -66,12 +96,15 @@ main (int argc, char *const *argv) static const struct GNUNET_GETOPT_CommandLineOption options[] = { GNUNET_GETOPT_OPTION_END }; + + struct vpn_cls* cls = (struct vpn_cls*)malloc(sizeof(struct vpn_cls)); + return (GNUNET_OK == GNUNET_PROGRAM_run (argc, argv, "gnunet-daemon-vpn", gettext_noop ("help text"), - options, &run, NULL)) ? ret : 1; + options, &run, cls)) ? ret : 1; } /* end of gnunet-daemon-vpn.c */ diff --git a/src/vpn/gnunet-vpn-helper.c b/src/vpn/gnunet-vpn-helper.c index a5a569b9a..602bc4cfd 100644 --- a/src/vpn/gnunet-vpn-helper.c +++ b/src/vpn/gnunet-vpn-helper.c @@ -10,6 +10,8 @@ #include +#include + #include #include @@ -27,6 +29,14 @@ struct in6_ifreq { #endif +int running = 1; + +void term(int sig) { + fprintf(stderr, "Got SIGTERM...\n"); + if (sig == SIGTERM) + running = 0; +} + static void set_address(char* dev, char* address, unsigned long prefix_len) { /* {{{ */ int fd = socket(AF_INET6, SOCK_DGRAM, 0); @@ -87,11 +97,12 @@ static int copy (int in, int out) { return 0; } - int main(int argc, char** argv) { char dev[IFNAMSIZ]; memset(dev, 0, IFNAMSIZ); + signal(SIGTERM, &term); + int fd_tun = init_tun(dev); fprintf(stderr, "Initialized the interface %s as %d.\n", dev, fd_tun); @@ -111,26 +122,42 @@ int main(int argc, char** argv) { fd_set fds_w; fd_set fds_r; - for(;;) { + + int r = 1; + int w = 1; + while(r != 0 && w != 0 && running == 1) { FD_ZERO(&fds_w); FD_ZERO(&fds_r); - FD_SET(0, &fds_r); - FD_SET(fd_tun, &fds_r); + if (r) { + FD_SET(fd_tun, &fds_r); + FD_SET(1, &fds_w); + } - FD_SET(1, &fds_w); - FD_SET(fd_tun, &fds_w); + if (w) { + FD_SET(0, &fds_r); + FD_SET(fd_tun, &fds_w); + } int r = select(fd_tun+1, &fds_r, &fds_w, (fd_set*)0, 0); if(r > 0) { if (FD_ISSET(0, &fds_r) && FD_ISSET(fd_tun, &fds_w)) { - copy(0, fd_tun); + if (copy(0, fd_tun) < 0) { + fprintf(stderr, "Closing Write\n"); + shutdown(fd_tun, SHUT_WR); + w = 0; + } } else if (FD_ISSET(1, &fds_w) && FD_ISSET(fd_tun, &fds_r)) { - copy(fd_tun, 1); + if (copy(fd_tun, 1) < 0) { + fprintf(stderr, "Closing Read\n"); + shutdown(fd_tun, SHUT_RD); + r = 0; + } } } } + fprintf(stderr, "Quitting!\n"); return 0; } -- 2.25.1