Make clang happy
[oweals/gnunet.git] / src / vpn / gnunet-daemon-vpn.c
index e9e944ca890cde07a7e3f8da777a0e8bc76f72b8..19824cc589df8d390501003573394d41b9c3a7e8 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2010 Philipp Tölke
+     (C) 2010 Christian Grothoff
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -30,6 +30,9 @@
 #include "gnunet-vpn-helper-p.h"
 #include "gnunet-vpn-packet.h"
 #include "gnunet-vpn-pretty-print.h"
+#include "gnunet_common.h"
+#include "gnunet_protocols.h"
+#include "gnunet_server_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;
+       struct GNUNET_DISK_PipeHandle* helper_in; // From the helper
+       struct GNUNET_DISK_PipeHandle* helper_out; // To the helper
        const struct GNUNET_DISK_FileHandle* fh_from_helper;
 
+       struct GNUNET_SERVER_MessageStreamTokenizer* mst;
+
        struct GNUNET_SCHEDULER_Handle *sched;
 
        pid_t helper_pid;
@@ -55,41 +60,58 @@ static void cleanup(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tskctx
        }
 }
 
-static void helper_read(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tsdkctx) {
+static void helper_read(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tsdkctx);
+
+static void start_helper_and_schedule(struct vpn_cls* mycls) {
+       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);
+
+       mycls->fh_from_helper = GNUNET_DISK_pipe_handle (mycls->helper_out, GNUNET_DISK_PIPE_END_READ);
+
+       GNUNET_DISK_pipe_close_end(mycls->helper_out, GNUNET_DISK_PIPE_END_WRITE);
+       GNUNET_DISK_pipe_close_end(mycls->helper_in, GNUNET_DISK_PIPE_END_READ);
+
+       GNUNET_SCHEDULER_add_read_file (mycls->sched, GNUNET_TIME_UNIT_FOREVER_REL, mycls->fh_from_helper, &helper_read, mycls);
+}
+
+
+static void restart_helper(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tskctx) {
        struct vpn_cls* mycls = (struct vpn_cls*) cls;
-       struct suid_packet_header hdr = { .size = 0 };
 
-       int r = 0;
+       // Kill the helper
+       PLIBC_KILL(mycls->helper_pid, SIGTERM);
+       GNUNET_OS_process_wait(mycls->helper_pid);
+
+       // Restart the helper
+       start_helper_and_schedule(mycls);
+
+}
+
+static void helper_read(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tsdkctx) {
+       struct vpn_cls* mycls = (struct vpn_cls*) cls;
+       char buf[65535];
 
        if (tsdkctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)
                return;
 
-       while (r < sizeof(struct suid_packet_header)) {
-               int t = GNUNET_DISK_file_read(mycls->fh_from_helper, &hdr, sizeof(struct suid_packet_header));
-               if (t< 0) {
-                       fprintf(stderr, "Read error for header: %m\n");
-                       return;
-               }
-               r += t;
+       int t = GNUNET_DISK_file_read(mycls->fh_from_helper, &buf, 65535);
+       if (t<=0) {
+               fprintf(stderr, "Read error for header: %m\n");
+               GNUNET_SCHEDULER_add_now(mycls->sched, restart_helper, cls);
+               return;
        }
 
-       struct suid_packet *pkt = (struct suid_packet*) GNUNET_malloc(ntohl(hdr.size));
+       /* FIXME */ GNUNET_SERVER_mst_receive(mycls->mst, NULL, buf, t, 0, 0);
 
-       if (memcpy(pkt, &hdr, sizeof(struct suid_packet_header)) < 0) {
-               fprintf(stderr, "Memcpy: %m\n");
-               return;
-       }
+       GNUNET_SCHEDULER_add_read_file (mycls->sched, GNUNET_TIME_UNIT_FOREVER_REL, mycls->fh_from_helper, &helper_read, mycls);
+}
 
-       while (r < ntohl(pkt->hdr.size)) {
-               int t = GNUNET_DISK_file_read(mycls->fh_from_helper, (unsigned char*)pkt + r, ntohl(pkt->hdr.size) - r);
-               if (t< 0) {
-                       fprintf(stderr, "Read error for data: %m\n");
-                       return;
-               }
-               r += t;
-       }
+static void message_token(void *cls, void *client, const struct GNUNET_MessageHeader *message) {
+       if (ntohs(message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) return;
 
-       struct ip6_pkt *pkt6 = (struct ip6_pkt*) pkt;
+       struct ip6_pkt *pkt6 = (struct ip6_pkt*) message;
        struct ip6_tcp *pkt6_tcp;
        struct ip6_udp *pkt6_udp;
 
@@ -108,9 +130,6 @@ static void helper_read(void* cls, const struct GNUNET_SCHEDULER_TaskContext* ts
                        break;
        }
 
-       GNUNET_free(pkt);
-
-       GNUNET_SCHEDULER_add_read_file (mycls->sched, GNUNET_TIME_UNIT_FOREVER_REL, mycls->fh_from_helper, &helper_read, mycls);
 }
 
 /**
@@ -133,16 +152,11 @@ run (void *cls,
 
        mycls->sched = sched;
 
-       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->mst = GNUNET_SERVER_mst_create(&message_token, mycls);
 
-       mycls->helper_pid = GNUNET_OS_start_process(mycls->helper_in, mycls->helper_out, "gnunet-vpn-helper", "gnunet-vpn-helper", NULL);
+       GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
 
-       mycls->fh_from_helper = GNUNET_DISK_pipe_handle (mycls->helper_out, GNUNET_DISK_PIPE_END_READ);
-       
-       GNUNET_SCHEDULER_add_read_file (sched, GNUNET_TIME_UNIT_FOREVER_REL, mycls->fh_from_helper, &helper_read, mycls);
+       start_helper_and_schedule(mycls);
 }
 
 
@@ -168,6 +182,8 @@ main (int argc, char *const *argv)
                               "gnunet-daemon-vpn",
                               gettext_noop ("help text"),
                               options, &run, cls)) ? ret : 1;
+
+  free(cls); // Make clang happy
 }
 
 /* end of gnunet-daemon-vpn.c */