gnunet-vpn-pretty-print.c gnunet-vpn-pretty-print.h \
gnunet-dns-parser.c gnunet-dns-parser.h \
gnunet-daemon-vpn-helper.c gnunet-daemon-vpn-helper.h \
- gnunet-daemon-vpn-dns.c gnunet-daemon-vpn-dns.h
+ gnunet-daemon-vpn-dns.c gnunet-daemon-vpn-dns.h \
+ gnunet-helper-vpn-api.c gnunet-helper-vpn-api.h
gnunet_daemon_vpn_LDADD = \
$(top_builddir)/src/core/libgnunetcore.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
#include "gnunet-service-dns-p.h"
#include "gnunet-vpn-packet.h"
-/**
- * PipeHandle to receive data from the helper
- */
-static struct GNUNET_DISK_PipeHandle* helper_in;
-
-/**
- * PipeHandle to send data to the helper
- */
-static struct GNUNET_DISK_PipeHandle* helper_out;
-
-/**
- * FileHandle to receive data from the helper
- */
-static const struct GNUNET_DISK_FileHandle* fh_from_helper;
-
-/**
- * FileHandle to send data to the helper
- */
-static const struct GNUNET_DISK_FileHandle* fh_to_helper;
-
/**
* Start the helper-process
+ *
+ * If cls != NULL it is assumed that this function is called as a result of a dying
+ * helper. cls is then taken as handle to the old helper and is cleaned up.
* {{{
*/
void
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
return;
- helper_in = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO);
- helper_out = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES);
-
- if (helper_in == NULL || helper_out == NULL) return;
+ if (cls != NULL)
+ cleanup_helper(cls);
+ cls = NULL;
+ char* ifname;
char* ipv6addr;
char* ipv6prefix;
char* ipv4addr;
char* ipv4mask;
+ if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "vpn", "IFNAME", &ifname))
+ {
+ GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "No entry 'IFNAME' in configuration!\n");
+ exit(1);
+ }
+
if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "vpn", "IPV6ADDR", &ipv6addr))
{
GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "No entry 'IPV6ADDR' in configuration!\n");
exit(1);
}
- helper_proc =
- GNUNET_OS_start_process (helper_in, helper_out, "gnunet-helper-vpn",
- "gnunet-helper-vpn", ipv6addr, ipv6prefix,
- ipv4addr, ipv4mask, NULL);
+ /* Start the helper
+ * Messages get passed to the function message_token
+ * When the helper dies, this function will be called again with the
+ * helper_handle as cls.
+ */
+ helper_handle = start_helper(ifname,
+ ipv6addr,
+ ipv6prefix,
+ ipv4addr,
+ ipv4mask,
+ "vpn-gnunet",
+ start_helper_and_schedule,
+ message_token,
+ NULL,
+ NULL);
GNUNET_free(ipv6addr);
GNUNET_free(ipv6prefix);
GNUNET_free(ipv4addr);
GNUNET_free(ipv4mask);
- fh_from_helper = GNUNET_DISK_pipe_handle (helper_out, GNUNET_DISK_PIPE_END_READ);
- fh_to_helper = GNUNET_DISK_pipe_handle (helper_in, GNUNET_DISK_PIPE_END_WRITE);
-
- GNUNET_DISK_pipe_close_end(helper_out, GNUNET_DISK_PIPE_END_WRITE);
- GNUNET_DISK_pipe_close_end(helper_in, GNUNET_DISK_PIPE_END_READ);
-
/* Tell the dns-service to rehijack the dns-port
* The routing-table gets flushed if an interface disappears.
*/
restart_hijack = 1;
GNUNET_CLIENT_notify_transmit_ready(dns_connection, sizeof(struct GNUNET_MessageHeader), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, &send_query, NULL);
-
- GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, fh_from_helper, &helper_read, NULL);
-}
-/*}}}*/
-/**
- * Restart the helper-process
- * {{{
- */
-void
-restart_helper(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tskctx) {
- // Kill the helper
- GNUNET_OS_process_kill (helper_proc, SIGKILL);
- GNUNET_OS_process_wait (helper_proc);
- GNUNET_OS_process_close (helper_proc);
- helper_proc = NULL;
-
- GNUNET_DISK_pipe_close(helper_in);
- GNUNET_DISK_pipe_close(helper_out);
-
- /* Restart the helper */
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, start_helper_and_schedule, NULL);
-}
-/*}}}*/
-
-/**
- * Read from the helper-process
- * {{{
- */
-void
-helper_read(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tsdkctx) {
- /* no message can be bigger then 64k */
- char buf[65535];
-
- if (tsdkctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)
- return;
-
- int t = GNUNET_DISK_file_read(fh_from_helper, &buf, 65535);
-
- /* On read-error, restart the helper */
- if (t<=0) {
- GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Read error for header from vpn-helper: %m\n");
- GNUNET_SCHEDULER_add_now(restart_helper, cls);
- return;
- }
-
- /* FIXME */ GNUNET_SERVER_mst_receive(mst, NULL, buf, t, 0, 0);
-
- GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, fh_from_helper, &helper_read, NULL);
}
/*}}}*/
GNUNET_CONTAINER_DLL_remove (answer_proc_head, answer_proc_tail, ans);
GNUNET_free(ans);
- /* FIXME */ GNUNET_DISK_file_write(fh_to_helper, pkt, pkt_len);
+ /* FIXME */ GNUNET_DISK_file_write(helper_handle->fh_to_helper, pkt, pkt_len);
/* if more packets are available, reschedule */
if (answer_proc_head != NULL)
GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
- fh_to_helper,
+ helper_handle->fh_to_helper,
&helper_write,
NULL);
}
void write_to_helper(void* buf, size_t len)
{
- (void)GNUNET_DISK_file_write(fh_to_helper, buf, len);
+ (void)GNUNET_DISK_file_write(helper_handle->fh_to_helper, buf, len);
}
void schedule_helper_write(struct GNUNET_TIME_Relative time, void* cls)
{
- GNUNET_SCHEDULER_add_write_file (time, fh_to_helper, &helper_write, cls);
+ GNUNET_SCHEDULER_add_write_file (time, helper_handle->fh_to_helper, &helper_write, cls);
}
#ifndef GNUNET_DAEMON_VPN_HELPER_H
#define GNUNET_DAEMON_VPN_HELPER_H
-/**
- * The process id of the helper
- */
-struct GNUNET_OS_Process *helper_proc;
+#include "gnunet-helper-vpn-api.h"
/**
- * The Message-Tokenizer that tokenizes the messages comming from the helper
+ * Handle to the helper. contains filedescriptors and such
*/
-struct GNUNET_SERVER_MessageStreamTokenizer* mst;
+struct GNUNET_VPN_HELPER_Handle *helper_handle;
/**
* Start the helper-process
const struct GNUNET_MessageHeader *message);
void write_to_helper(void* buf, size_t len);
-// GNUNET_DISK_file_write(fh_to_helper, response, ntohs(response->shdr.size));
void schedule_helper_write(struct GNUNET_TIME_Relative, void* cls);
-// GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, fh_to_helper, &helper_write, NULL);
#endif /* end of include guard: GNUNET-DAEMON-VPN-HELPER_H */
#include "gnunet-vpn-packet.h"
#include "gnunet-vpn-pretty-print.h"
#include "gnunet_common.h"
-#include <gnunet_os_lib.h>
#include "gnunet_protocols.h"
#include <gnunet_mesh_service.h>
#include "gnunet_client_lib.h"
GNUNET_assert (0 != (tskctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN));
/* stop the helper */
- if (helper_proc != NULL)
- {
- if (0 != GNUNET_OS_process_kill (helper_proc, SIGTERM))
- GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "kill");
- GNUNET_OS_process_wait (helper_proc);
- GNUNET_OS_process_close (helper_proc);
- helper_proc = NULL;
- }
+ cleanup_helper(helper_handle);
/* close the connection to the service-dns */
if (dns_connection != NULL)
NULL,
NULL,
handlers);
- mst = GNUNET_SERVER_mst_create(&message_token, NULL);
cfg = cfg_;
restart_hijack = 0;
hashmap = GNUNET_CONTAINER_multihashmap_create(65536);
--- /dev/null
+/*
+ This file is part of GNUnet.
+ (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
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet 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 GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file vpn/gnunet-helper-vpn-api.c
+ * @brief exposes the API (the convenience-functions) of dealing with the
+ * helper-vpn
+ * @author Philipp Toelke
+ */
+
+#include <platform.h>
+#include <gnunet_common.h>
+#include <gnunet_server_lib.h>
+#include <gnunet_os_lib.h>
+
+#include "gnunet-helper-vpn-api.h"
+
+static void
+stop_helper (struct GNUNET_VPN_HELPER_Handle *handle)
+{
+ if (NULL == handle->helper_proc)
+ return;
+ GNUNET_OS_process_kill (handle->helper_proc, SIGKILL);
+ GNUNET_OS_process_wait (handle->helper_proc);
+ GNUNET_OS_process_close (handle->helper_proc);
+ handle->helper_proc = NULL;
+
+ GNUNET_DISK_pipe_close (handle->helper_in);
+ GNUNET_DISK_pipe_close (handle->helper_out);
+}
+
+/**
+ * Read from the helper-process
+ */
+static void
+helper_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tsdkctx)
+{
+ struct GNUNET_VPN_HELPER_Handle *handle = cls;
+ /* no message can be bigger then 64k */
+ char buf[65535];
+
+ if (tsdkctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)
+ return;
+
+ int t = GNUNET_DISK_file_read (handle->fh_from_helper, &buf, 65535);
+
+ /* On read-error, restart the helper */
+ if (t <= 0)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Read error for header from vpn-helper: %m\n");
+ stop_helper (handle);
+
+ /* Restart the helper */
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
+ handle->restart_task, handle);
+ return;
+ }
+
+ /* FIXME */ GNUNET_SERVER_mst_receive (handle->mst, handle->client, buf, t,
+ 0, 0);
+
+ GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+ handle->fh_from_helper, &helper_read,
+ handle);
+}
+
+void
+cleanup_helper (struct GNUNET_VPN_HELPER_Handle *handle)
+{
+ stop_helper (handle);
+ GNUNET_free (handle);
+}
+
+struct GNUNET_VPN_HELPER_Handle *
+start_helper (const char *ifname,
+ const char *ipv6addr,
+ const char *ipv6prefix,
+ const char *ipv4addr,
+ const char *ipv4mask, const char *process_name,
+ GNUNET_SCHEDULER_Task restart_task,
+ GNUNET_SERVER_MessageTokenizerCallback cb, void *cb_cls,
+ void *client)
+{
+ struct GNUNET_VPN_HELPER_Handle *handle =
+ GNUNET_malloc (sizeof (struct GNUNET_VPN_HELPER_Handle));
+
+ handle->helper_in = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO);
+ handle->helper_out = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES);
+
+ handle->restart_task = restart_task;
+
+ if (handle->helper_in == NULL || handle->helper_out == NULL)
+ {
+ GNUNET_free (handle);
+ return NULL;
+ }
+
+ handle->helper_proc =
+ GNUNET_OS_start_process (handle->helper_in, handle->helper_out,
+ "gnunet-helper-vpn", process_name, ifname,
+ ipv6addr, ipv6prefix, ipv4addr, ipv4mask, NULL);
+
+ handle->fh_from_helper =
+ GNUNET_DISK_pipe_handle (handle->helper_out, GNUNET_DISK_PIPE_END_READ);
+ handle->fh_to_helper =
+ GNUNET_DISK_pipe_handle (handle->helper_in, GNUNET_DISK_PIPE_END_WRITE);
+
+ GNUNET_DISK_pipe_close_end (handle->helper_out, GNUNET_DISK_PIPE_END_WRITE);
+ GNUNET_DISK_pipe_close_end (handle->helper_in, GNUNET_DISK_PIPE_END_READ);
+
+ handle->mst = GNUNET_SERVER_mst_create (cb, cb_cls);
+
+ GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+ handle->fh_from_helper, &helper_read,
+ handle);
+
+ return handle;
+}
--- /dev/null
+/*
+ This file is part of GNUnet.
+ (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
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet 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 GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file vpn/gnunet-helper-vpn-api.h
+ * @brief exposes the API (the convenience-functions) of dealing with the
+ * helper-vpn
+ * @author Philipp Toelke
+ */
+#ifndef GNUNET_HELPER_VPN_API_H
+#define GNUNET_HELPER_VPN_API_H
+
+/**
+ * The handle to a helper.
+ * sometimes a few entries may be made opaque.
+ */
+struct GNUNET_VPN_HELPER_Handle
+{
+/**
+ * PipeHandle to receive data from the helper
+ */
+ struct GNUNET_DISK_PipeHandle *helper_in;
+
+/**
+ * PipeHandle to send data to the helper
+ */
+ struct GNUNET_DISK_PipeHandle *helper_out;
+
+/**
+ * FileHandle to receive data from the helper
+ */
+ const struct GNUNET_DISK_FileHandle *fh_from_helper;
+
+/**
+ * FileHandle to send data to the helper
+ */
+ const struct GNUNET_DISK_FileHandle *fh_to_helper;
+
+ /**
+ * The process id of the helper
+ */
+ struct GNUNET_OS_Process *helper_proc;
+
+ /**
+ * The Message-Tokenizer that tokenizes the messages comming from the helper
+ */
+ struct GNUNET_SERVER_MessageStreamTokenizer *mst;
+
+ /**
+ * The client-identifier passed to the mst-callback
+ */
+ void *client;
+
+ /**
+ * The name of the interface
+ */
+ char *ifname;
+
+ /**
+ * The task called when the helper dies.
+ * Will be called with the handle as cls
+ */
+ GNUNET_SCHEDULER_Task restart_task;
+};
+
+/**
+ * @brief Starts a helper and begins reading from it
+ *
+ * @param ifname The name of the new interface
+ * @param ipv6addr The IPv6 address of the new interface
+ * @param ipv6prefix The IPv6 prefix length of the new IP
+ * @param ipv4addr The IPv4 address of the new interface
+ * @param ipv4mask The associated netmask
+ * @param process_name How the helper should appear in process-listings
+ * @param restart_task The task called when the helper dies. Will be called with the handle as cls
+ * @param cb A callback for messages from the helper
+ * @param cb_cls Closure for the callback
+ * @param client client_name for the callback
+ *
+ * @return A pointer to the new Handle, NULL on error
+ */
+struct GNUNET_VPN_HELPER_Handle *start_helper (const char *ifname,
+ const char *ipv6addr,
+ const char *ipv6prefix,
+ const char *ipv4addr,
+ const char *ipv4mask,
+ const char *process_name,
+ GNUNET_SCHEDULER_Task
+ restart_task,
+ GNUNET_SERVER_MessageTokenizerCallback
+ cb, void *cb_cls,
+ void *client);
+
+/**
+ * @brief Kills the helper, closes the pipe and free()s the handle
+ */
+void cleanup_helper (struct GNUNET_VPN_HELPER_Handle *);
+
+#endif /* end of include guard: GNUNET_HELPER_VPN_API_H */