gnunet-helper-vpn-api.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. This file is part of GNUnet.
  3. (C) 2010 Christian Grothoff
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file vpn/gnunet-helper-vpn-api.c
  19. * @brief exposes the API (the convenience-functions) of dealing with the
  20. * helper-vpn
  21. * @author Philipp Toelke
  22. */
  23. #include <platform.h>
  24. #include <gnunet_common.h>
  25. #include <gnunet_server_lib.h>
  26. #include <gnunet_os_lib.h>
  27. #include "gnunet-helper-vpn-api.h"
  28. static void
  29. stop_helper (struct GNUNET_VPN_HELPER_Handle *handle)
  30. {
  31. if (NULL == handle->helper_proc)
  32. return;
  33. GNUNET_OS_process_kill (handle->helper_proc, SIGKILL);
  34. GNUNET_OS_process_wait (handle->helper_proc);
  35. GNUNET_OS_process_close (handle->helper_proc);
  36. handle->helper_proc = NULL;
  37. GNUNET_DISK_pipe_close (handle->helper_in);
  38. GNUNET_DISK_pipe_close (handle->helper_out);
  39. GNUNET_SERVER_mst_destroy(handle->mst);
  40. }
  41. extern GNUNET_SCHEDULER_TaskIdentifier shs_task;
  42. /**
  43. * Read from the helper-process
  44. */
  45. static void
  46. helper_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tsdkctx)
  47. {
  48. struct GNUNET_VPN_HELPER_Handle *handle = cls;
  49. /* no message can be bigger then 64k */
  50. char buf[65535];
  51. if (tsdkctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)
  52. return;
  53. int t = GNUNET_DISK_file_read (handle->fh_from_helper, &buf, 65535);
  54. /* On read-error, restart the helper */
  55. if (t <= 0)
  56. {
  57. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  58. "Read error for header from vpn-helper: %m\n");
  59. stop_helper (handle);
  60. /* Restart the helper */
  61. shs_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
  62. handle->restart_task, handle);
  63. return;
  64. }
  65. if (GNUNET_SYSERR ==
  66. GNUNET_SERVER_mst_receive (handle->mst, handle->client, buf, t, 0, 0))
  67. {
  68. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  69. "SYSERR from mst\n");
  70. stop_helper (handle);
  71. /* Restart the helper */
  72. shs_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
  73. handle->restart_task, handle);
  74. return;
  75. }
  76. GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
  77. handle->fh_from_helper, &helper_read,
  78. handle);
  79. }
  80. void
  81. cleanup_helper (struct GNUNET_VPN_HELPER_Handle *handle)
  82. {
  83. stop_helper (handle);
  84. GNUNET_free (handle);
  85. }
  86. struct GNUNET_VPN_HELPER_Handle *
  87. start_helper (const char *ifname,
  88. const char *ipv6addr,
  89. const char *ipv6prefix,
  90. const char *ipv4addr,
  91. const char *ipv4mask, const char *process_name,
  92. GNUNET_SCHEDULER_Task restart_task,
  93. GNUNET_SERVER_MessageTokenizerCallback cb, void *cb_cls)
  94. {
  95. struct GNUNET_VPN_HELPER_Handle *handle =
  96. GNUNET_malloc (sizeof (struct GNUNET_VPN_HELPER_Handle));
  97. handle->helper_in = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO);
  98. handle->helper_out = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES);
  99. handle->restart_task = restart_task;
  100. if (handle->helper_in == NULL || handle->helper_out == NULL)
  101. {
  102. GNUNET_free (handle);
  103. return NULL;
  104. }
  105. handle->helper_proc =
  106. GNUNET_OS_start_process (handle->helper_in, handle->helper_out,
  107. "gnunet-helper-vpn", process_name, ifname,
  108. ipv6addr, ipv6prefix, ipv4addr, ipv4mask, NULL);
  109. handle->fh_from_helper =
  110. GNUNET_DISK_pipe_handle (handle->helper_out, GNUNET_DISK_PIPE_END_READ);
  111. handle->fh_to_helper =
  112. GNUNET_DISK_pipe_handle (handle->helper_in, GNUNET_DISK_PIPE_END_WRITE);
  113. GNUNET_DISK_pipe_close_end (handle->helper_out, GNUNET_DISK_PIPE_END_WRITE);
  114. GNUNET_DISK_pipe_close_end (handle->helper_in, GNUNET_DISK_PIPE_END_READ);
  115. handle->mst = GNUNET_SERVER_mst_create (cb, cb_cls);
  116. GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
  117. handle->fh_from_helper, &helper_read,
  118. handle);
  119. return handle;
  120. }