invokecharon.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /*
  2. * Copyright (C) 2006 Martin Willi
  3. * HSR Hochschule fuer Technik Rapperswil
  4. *
  5. * Copyright (C) 2001-2002 Mathieu Lafon
  6. * Arkoon Network Security
  7. *
  8. * Ported from invokepluto.c to fit charons needs.
  9. *
  10. * This program is free software; you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License as published by the
  12. * Free Software Foundation; either version 2 of the License, or (at your
  13. * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
  14. *
  15. * This program is distributed in the hope that it will be useful, but
  16. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  17. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  18. * for more details.
  19. */
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include <unistd.h>
  23. #include <signal.h>
  24. #include <string.h>
  25. #include <stdlib.h>
  26. #include <errno.h>
  27. #include <library.h>
  28. #include <utils/debug.h>
  29. #include "confread.h"
  30. #include "invokecharon.h"
  31. #include "files.h"
  32. static int _charon_pid = 0;
  33. static int _stop_requested;
  34. pid_t starter_charon_pid(void)
  35. {
  36. return _charon_pid;
  37. }
  38. void starter_charon_sigchild(pid_t pid, int status)
  39. {
  40. if (pid == _charon_pid)
  41. {
  42. _charon_pid = 0;
  43. if (status == SS_RC_LIBSTRONGSWAN_INTEGRITY ||
  44. status == SS_RC_DAEMON_INTEGRITY)
  45. {
  46. DBG1(DBG_APP, "%s has quit: integrity test of %s failed",
  47. daemon_name, (status == 64) ? "libstrongswan" : daemon_name);
  48. _stop_requested = 1;
  49. }
  50. else if (status == SS_RC_INITIALIZATION_FAILED)
  51. {
  52. DBG1(DBG_APP, "%s has quit: initialization failed", daemon_name);
  53. _stop_requested = 1;
  54. }
  55. if (!_stop_requested)
  56. {
  57. DBG1(DBG_APP, "%s has died -- restart scheduled (%dsec)",
  58. daemon_name, CHARON_RESTART_DELAY);
  59. alarm(CHARON_RESTART_DELAY); // restart in 5 sec
  60. }
  61. unlink(pid_file);
  62. }
  63. }
  64. int starter_stop_charon (void)
  65. {
  66. int i;
  67. pid_t pid = _charon_pid;
  68. if (pid)
  69. {
  70. _stop_requested = 1;
  71. /* be more and more aggressive */
  72. for (i = 0; i < 50 && (pid = _charon_pid) != 0; i++)
  73. {
  74. if (i == 0)
  75. {
  76. kill(pid, SIGINT);
  77. }
  78. else if (i < 40)
  79. {
  80. kill(pid, SIGTERM);
  81. }
  82. else if (i == 40)
  83. {
  84. kill(pid, SIGKILL);
  85. DBG1(DBG_APP, "starter_stop_charon(): %s does not respond, sending KILL",
  86. daemon_name);
  87. }
  88. else
  89. {
  90. kill(pid, SIGKILL);
  91. }
  92. usleep(200000); /* sleep for 200 ms */
  93. }
  94. if (_charon_pid == 0)
  95. {
  96. DBG1(DBG_APP, "%s stopped after %d ms", daemon_name, 200*i);
  97. return 0;
  98. }
  99. DBG1(DBG_APP, "starter_stop_charon(): can't stop %s !!!", daemon_name);
  100. return -1;
  101. }
  102. else
  103. {
  104. DBG1(DBG_APP, "stater_stop_charon(): %s was not started...", daemon_name);
  105. }
  106. return -1;
  107. }
  108. int starter_start_charon (starter_config_t *cfg, bool no_fork, bool attach_gdb)
  109. {
  110. struct stat stb;
  111. int pid, i;
  112. char buffer[BUF_LEN];
  113. int argc = 1;
  114. char *arg[] = {
  115. cmd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  116. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  117. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  118. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
  119. };
  120. if (attach_gdb)
  121. {
  122. argc = 0;
  123. arg[argc++] = "/usr/bin/gdb";
  124. arg[argc++] = "--args";
  125. arg[argc++] = cmd;
  126. }
  127. if (!no_fork)
  128. {
  129. arg[argc++] = "--use-syslog";
  130. }
  131. /* parse debug string */
  132. {
  133. int level;
  134. char type[4];
  135. char *pos = cfg->setup.charondebug;
  136. char *buf_pos = buffer;
  137. while (pos && sscanf(pos, "%3s %d,", type, &level) == 2)
  138. {
  139. snprintf(buf_pos, buffer + sizeof(buffer) - buf_pos, "--debug-%s", type);
  140. arg[argc++] = buf_pos;
  141. buf_pos += strlen(buf_pos) + 1;
  142. if (buf_pos >= buffer + sizeof(buffer))
  143. {
  144. break;
  145. }
  146. snprintf(buf_pos, buffer + sizeof(buffer) - buf_pos, "%d", level);
  147. arg[argc++] = buf_pos;
  148. buf_pos += strlen(buf_pos) + 1;
  149. if (buf_pos >= buffer + sizeof(buffer))
  150. {
  151. break;
  152. }
  153. /* get next */
  154. pos = strchr(pos, ',');
  155. if (pos)
  156. {
  157. pos++;
  158. }
  159. }
  160. }
  161. if (_charon_pid)
  162. {
  163. DBG1(DBG_APP, "starter_start_charon(): %s already started...",
  164. daemon_name);
  165. return -1;
  166. }
  167. else
  168. {
  169. unlink(CHARON_CTL_FILE);
  170. _stop_requested = 0;
  171. pid = fork();
  172. switch (pid)
  173. {
  174. case -1:
  175. DBG1(DBG_APP, "can't fork(): %s", strerror(errno));
  176. return -1;
  177. case 0:
  178. /* child */
  179. setsid();
  180. closefrom(3);
  181. sigprocmask(SIG_SETMASK, 0, NULL);
  182. /* disable glibc's malloc checker, conflicts with leak detective */
  183. setenv("MALLOC_CHECK_", "0", 1);
  184. execv(arg[0], arg);
  185. DBG1(DBG_APP, "can't execv(%s,...): %s", arg[0], strerror(errno));
  186. exit(1);
  187. default:
  188. /* father */
  189. _charon_pid = pid;
  190. while (attach_gdb)
  191. {
  192. /* wait indefinitely if gdb is attached */
  193. usleep(10000);
  194. if (stat(pid_file, &stb) == 0)
  195. {
  196. return 0;
  197. }
  198. }
  199. for (i = 0; i < 500 && _charon_pid; i++)
  200. {
  201. /* wait for charon for a maximum of 500 x 20 ms = 10 s */
  202. usleep(20000);
  203. if (stat(pid_file, &stb) == 0)
  204. {
  205. DBG1(DBG_APP, "%s (%d) started after %d ms", daemon_name,
  206. _charon_pid, 20*(i+1));
  207. return 0;
  208. }
  209. }
  210. if (_charon_pid)
  211. {
  212. /* If charon is started but with no ctl file, stop it */
  213. DBG1(DBG_APP, "%s too long to start... - kill kill",
  214. daemon_name);
  215. for (i = 0; i < 20 && (pid = _charon_pid) != 0; i++)
  216. {
  217. if (i == 0)
  218. {
  219. kill(pid, SIGINT);
  220. }
  221. else if (i < 10)
  222. {
  223. kill(pid, SIGTERM);
  224. }
  225. else
  226. {
  227. kill(pid, SIGKILL);
  228. }
  229. usleep(20000); /* sleep for 20 ms */
  230. }
  231. }
  232. else
  233. {
  234. DBG1(DBG_APP, "%s refused to be started", daemon_name);
  235. }
  236. return -1;
  237. }
  238. }
  239. return -1;
  240. }