#include "platform.h"
#include "gnunet_getopt_lib.h"
#include "gnunet_program_lib.h"
+#include "gnunet_os_lib.h"
/* #include "gnunet_template_service.h" */
/**
*/
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.
*
*/
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);
}
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 */
#include <string.h>
+#include <signal.h>
+
#include <stdio.h>
#include <unistd.h>
#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);
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);
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;
}