You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rspamd.c 37KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422
  1. /*-
  2. * Copyright 2016 Vsevolod Stakhov
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "config.h"
  17. #include "rspamd.h"
  18. #include "libutil/map.h"
  19. #include "lua/lua_common.h"
  20. #include "libserver/worker_util.h"
  21. #include "libserver/rspamd_control.h"
  22. #include "ottery.h"
  23. #include "cryptobox.h"
  24. #include "utlist.h"
  25. #include "unix-std.h"
  26. /* sysexits */
  27. #ifdef HAVE_SYSEXITS_H
  28. #include <sysexits.h>
  29. #endif
  30. /* pwd and grp */
  31. #ifdef HAVE_PWD_H
  32. #include <pwd.h>
  33. #endif
  34. #ifdef HAVE_GRP_H
  35. #include <grp.h>
  36. #endif
  37. #ifdef HAVE_NFTW
  38. #include <ftw.h>
  39. #endif
  40. #include <signal.h>
  41. #ifdef HAVE_SYS_WAIT_H
  42. #include <sys/wait.h>
  43. #endif
  44. #ifdef HAVE_SYS_RESOURCE_H
  45. #include <sys/resource.h>
  46. #endif
  47. #ifdef HAVE_LIBUTIL_H
  48. #include <libutil.h>
  49. #endif
  50. #ifdef WITH_GPERF_TOOLS
  51. #include <gperftools/profiler.h>
  52. #endif
  53. #ifdef HAVE_STROPS_H
  54. #include <stropts.h>
  55. #endif
  56. #ifdef HAVE_OPENSSL
  57. #include <openssl/err.h>
  58. #include <openssl/evp.h>
  59. #endif
  60. #include "sqlite3.h"
  61. #include "contrib/libev/ev.h"
  62. /* 2 seconds to fork new process in place of dead one */
  63. #define SOFT_FORK_TIME 2
  64. /* 10 seconds after getting termination signal to terminate all workers with SIGKILL */
  65. #define TERMINATION_ATTEMPTS 50
  66. static gboolean load_rspamd_config (struct rspamd_main *rspamd_main,
  67. struct rspamd_config *cfg,
  68. gboolean init_modules,
  69. enum rspamd_post_load_options opts,
  70. gboolean reload);
  71. static void rspamd_cld_handler (EV_P_ ev_child *w,
  72. struct rspamd_main *rspamd_main,
  73. struct rspamd_worker *wrk);
  74. /* Control socket */
  75. static gint control_fd;
  76. static ev_io control_ev;
  77. static gboolean valgrind_mode = FALSE;
  78. /* Cmdline options */
  79. static gboolean no_fork = FALSE;
  80. static gboolean show_version = FALSE;
  81. static gchar **cfg_names = NULL;
  82. static gchar *rspamd_user = NULL;
  83. static gchar *rspamd_group = NULL;
  84. static gchar *rspamd_pidfile = NULL;
  85. static gboolean is_debug = FALSE;
  86. static gboolean is_insecure = FALSE;
  87. static GHashTable *ucl_vars = NULL;
  88. static gchar **lua_env = NULL;
  89. static gboolean skip_template = FALSE;
  90. static gint term_attempts = 0;
  91. /* List of active listen sockets indexed by worker type */
  92. static GHashTable *listen_sockets = NULL;
  93. /* Defined in modules.c */
  94. extern module_t *modules[];
  95. extern worker_t *workers[];
  96. /* Command line options */
  97. static gboolean rspamd_parse_var (const gchar *option_name,
  98. const gchar *value, gpointer data,
  99. GError **error);
  100. static GOptionEntry entries[] =
  101. {
  102. { "no-fork", 'f', 0, G_OPTION_ARG_NONE, &no_fork,
  103. "Do not daemonize main process", NULL },
  104. { "config", 'c', 0, G_OPTION_ARG_FILENAME_ARRAY, &cfg_names,
  105. "Specify config file(s)", NULL },
  106. { "user", 'u', 0, G_OPTION_ARG_STRING, &rspamd_user,
  107. "User to run rspamd as", NULL },
  108. { "group", 'g', 0, G_OPTION_ARG_STRING, &rspamd_group,
  109. "Group to run rspamd as", NULL },
  110. { "pid", 'p', 0, G_OPTION_ARG_STRING, &rspamd_pidfile, "Path to pidfile",
  111. NULL },
  112. { "debug", 'd', 0, G_OPTION_ARG_NONE, &is_debug, "Force debug output",
  113. NULL },
  114. { "insecure", 'i', 0, G_OPTION_ARG_NONE, &is_insecure,
  115. "Ignore running workers as privileged users (insecure)", NULL },
  116. { "version", 'v', 0, G_OPTION_ARG_NONE, &show_version,
  117. "Show version and exit", NULL },
  118. {"var", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer)&rspamd_parse_var,
  119. "Redefine/define environment variable", NULL},
  120. {"skip-template", 'T', 0, G_OPTION_ARG_NONE, &skip_template,
  121. "Do not apply Jinja templates", NULL},
  122. {"lua-env", '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &lua_env,
  123. "Load lua environment from the specified files", NULL},
  124. { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
  125. };
  126. static gboolean
  127. rspamd_parse_var (const gchar *option_name,
  128. const gchar *value, gpointer data,
  129. GError **error)
  130. {
  131. gchar *k, *v, *t;
  132. t = strchr (value, '=');
  133. if (t != NULL) {
  134. k = g_strdup (value);
  135. t = k + (t - value);
  136. v = g_strdup (t + 1);
  137. *t = '\0';
  138. g_hash_table_insert (ucl_vars, k, v);
  139. }
  140. else {
  141. g_set_error (error, g_quark_try_string ("main"), EINVAL,
  142. "Bad variable format: %s", value);
  143. return FALSE;
  144. }
  145. return TRUE;
  146. }
  147. static void
  148. read_cmd_line (gint *argc, gchar ***argv, struct rspamd_config *cfg)
  149. {
  150. GError *error = NULL;
  151. GOptionContext *context;
  152. guint cfg_num;
  153. context = g_option_context_new ("- run rspamd daemon");
  154. #if defined(GIT_VERSION) && GIT_VERSION == 1
  155. g_option_context_set_summary (context,
  156. "Summary:\n Rspamd daemon version " RVERSION "-git\n Git id: " RID);
  157. #else
  158. g_option_context_set_summary (context,
  159. "Summary:\n Rspamd daemon version " RVERSION);
  160. #endif
  161. g_option_context_add_main_entries (context, entries, NULL);
  162. if (!g_option_context_parse (context, argc, argv, &error)) {
  163. fprintf (stderr, "option parsing failed: %s\n", error->message);
  164. g_option_context_free (context);
  165. exit (1);
  166. }
  167. cfg->rspamd_user = rspamd_user;
  168. cfg->rspamd_group = rspamd_group;
  169. cfg_num = cfg_names != NULL ? g_strv_length (cfg_names) : 0;
  170. if (cfg_num == 0) {
  171. cfg->cfg_name = FIXED_CONFIG_FILE;
  172. }
  173. else {
  174. cfg->cfg_name = cfg_names[0];
  175. g_assert (cfg_num == 1);
  176. }
  177. cfg->pid_file = rspamd_pidfile;
  178. g_option_context_free (context);
  179. }
  180. /* Detect privilleged mode */
  181. static void
  182. detect_priv (struct rspamd_main *rspamd_main)
  183. {
  184. struct passwd *pwd;
  185. struct group *grp;
  186. uid_t euid;
  187. euid = geteuid ();
  188. if (euid == 0) {
  189. if (!rspamd_main->cfg->rspamd_user && !is_insecure) {
  190. msg_err_main (
  191. "cannot run rspamd workers as root user, please add -u and -g options to select a proper unprivilleged user or specify --insecure flag");
  192. exit (EXIT_FAILURE);
  193. }
  194. else if (is_insecure) {
  195. rspamd_main->is_privilleged = TRUE;
  196. rspamd_main->workers_uid = 0;
  197. rspamd_main->workers_gid = 0;
  198. }
  199. else {
  200. rspamd_main->is_privilleged = TRUE;
  201. pwd = getpwnam (rspamd_main->cfg->rspamd_user);
  202. if (pwd == NULL) {
  203. msg_err_main ("user specified does not exists (%s), aborting",
  204. strerror (errno));
  205. exit (-errno);
  206. }
  207. if (rspamd_main->cfg->rspamd_group) {
  208. grp = getgrnam (rspamd_main->cfg->rspamd_group);
  209. if (grp == NULL) {
  210. msg_err_main ("group specified does not exists (%s), aborting",
  211. strerror (errno));
  212. exit (-errno);
  213. }
  214. rspamd_main->workers_gid = grp->gr_gid;
  215. }
  216. else {
  217. rspamd_main->workers_gid = (gid_t)-1;
  218. }
  219. rspamd_main->workers_uid = pwd->pw_uid;
  220. }
  221. }
  222. else {
  223. rspamd_main->is_privilleged = FALSE;
  224. rspamd_main->workers_uid = (uid_t)-1;
  225. rspamd_main->workers_gid = (gid_t)-1;
  226. }
  227. }
  228. static void
  229. config_logger (rspamd_mempool_t *pool, gpointer ud)
  230. {
  231. struct rspamd_main *rspamd_main = ud;
  232. rspamd_set_logger (rspamd_main->cfg, g_quark_try_string ("main"),
  233. &rspamd_main->logger, rspamd_main->server_pool);
  234. if (rspamd_log_open_priv (rspamd_main->logger,
  235. rspamd_main->workers_uid, rspamd_main->workers_gid) == -1) {
  236. fprintf (stderr, "Fatal error, cannot open logfile, exiting\n");
  237. exit (EXIT_FAILURE);
  238. }
  239. rspamd_logger_configure_modules (rspamd_main->cfg->debug_modules);
  240. }
  241. static void
  242. reread_config (struct rspamd_main *rspamd_main)
  243. {
  244. struct rspamd_config *tmp_cfg, *old_cfg;
  245. gchar *cfg_file;
  246. int load_opts = RSPAMD_CONFIG_INIT_VALIDATE|RSPAMD_CONFIG_INIT_SYMCACHE|
  247. RSPAMD_CONFIG_INIT_LIBS|RSPAMD_CONFIG_INIT_URL;
  248. rspamd_symcache_save (rspamd_main->cfg->cache);
  249. tmp_cfg = rspamd_config_new (RSPAMD_CONFIG_INIT_DEFAULT);
  250. tmp_cfg->libs_ctx = rspamd_main->cfg->libs_ctx;
  251. REF_RETAIN (tmp_cfg->libs_ctx);
  252. cfg_file = rspamd_mempool_strdup (tmp_cfg->cfg_pool,
  253. rspamd_main->cfg->cfg_name);
  254. /* Save some variables */
  255. tmp_cfg->cfg_name = cfg_file;
  256. old_cfg = rspamd_main->cfg;
  257. rspamd_main->cfg = tmp_cfg;
  258. if (!load_rspamd_config (rspamd_main, tmp_cfg, TRUE, load_opts, TRUE)) {
  259. rspamd_main->cfg = old_cfg;
  260. rspamd_log_close_priv (rspamd_main->logger,
  261. FALSE,
  262. rspamd_main->workers_uid,
  263. rspamd_main->workers_gid);
  264. rspamd_set_logger (rspamd_main->cfg, g_quark_try_string ("main"),
  265. &rspamd_main->logger, rspamd_main->server_pool);
  266. rspamd_log_open_priv (rspamd_main->logger,
  267. rspamd_main->workers_uid,
  268. rspamd_main->workers_gid);
  269. msg_err_main ("cannot parse new config file, revert to old one");
  270. REF_RELEASE (tmp_cfg);
  271. }
  272. else {
  273. msg_info_main ("replacing config");
  274. REF_RELEASE (old_cfg);
  275. rspamd_main->cfg->rspamd_user = rspamd_user;
  276. rspamd_main->cfg->rspamd_group = rspamd_group;
  277. /* Here, we can do post actions with the existing config */
  278. /*
  279. * As some rules are defined in lua, we need to process them, then init
  280. * modules and merely afterwards to init modules
  281. */
  282. rspamd_lua_post_load_config (tmp_cfg);
  283. rspamd_init_filters (tmp_cfg, TRUE);
  284. /* Do post-load actions */
  285. rspamd_config_post_load (tmp_cfg,
  286. load_opts|RSPAMD_CONFIG_INIT_POST_LOAD_LUA|RSPAMD_CONFIG_INIT_PRELOAD_MAPS);
  287. msg_info_main ("config has been reread successfully");
  288. }
  289. }
  290. struct waiting_worker {
  291. struct rspamd_main *rspamd_main;
  292. struct ev_timer wait_ev;
  293. struct rspamd_worker_conf *cf;
  294. guint oldindex;
  295. };
  296. static void
  297. rspamd_fork_delayed_cb (EV_P_ ev_timer *w, int revents)
  298. {
  299. struct waiting_worker *waiting_worker = (struct waiting_worker *)w->data;
  300. ev_timer_stop (EV_A_ &waiting_worker->wait_ev);
  301. rspamd_fork_worker (waiting_worker->rspamd_main, waiting_worker->cf,
  302. waiting_worker->oldindex,
  303. waiting_worker->rspamd_main->event_loop,
  304. rspamd_cld_handler);
  305. REF_RELEASE (waiting_worker->cf);
  306. g_free (waiting_worker);
  307. }
  308. static void
  309. rspamd_fork_delayed (struct rspamd_worker_conf *cf,
  310. guint index,
  311. struct rspamd_main *rspamd_main)
  312. {
  313. struct waiting_worker *nw;
  314. struct timeval tv;
  315. nw = g_malloc0 (sizeof (*nw));
  316. nw->cf = cf;
  317. nw->oldindex = index;
  318. nw->rspamd_main = rspamd_main;
  319. tv.tv_sec = SOFT_FORK_TIME;
  320. tv.tv_usec = 0;
  321. REF_RETAIN (cf);
  322. nw->wait_ev.data = nw;
  323. ev_timer_init (&nw->wait_ev, rspamd_fork_delayed_cb, SOFT_FORK_TIME, 0.0);
  324. ev_timer_start (rspamd_main->event_loop, &nw->wait_ev);
  325. }
  326. static GList *
  327. create_listen_socket (GPtrArray *addrs, guint cnt,
  328. enum rspamd_worker_socket_type listen_type)
  329. {
  330. GList *result = NULL;
  331. gint fd;
  332. guint i;
  333. struct rspamd_worker_listen_socket *ls;
  334. g_ptr_array_sort (addrs, rspamd_inet_address_compare_ptr);
  335. for (i = 0; i < cnt; i ++) {
  336. /*
  337. * Copy address to avoid reload issues
  338. */
  339. if (listen_type & RSPAMD_WORKER_SOCKET_TCP) {
  340. fd = rspamd_inet_address_listen (g_ptr_array_index (addrs, i),
  341. SOCK_STREAM, TRUE);
  342. if (fd != -1) {
  343. ls = g_malloc0 (sizeof (*ls));
  344. ls->addr = rspamd_inet_address_copy (g_ptr_array_index (addrs, i));
  345. ls->fd = fd;
  346. ls->type = RSPAMD_WORKER_SOCKET_TCP;
  347. result = g_list_prepend (result, ls);
  348. }
  349. }
  350. if (listen_type & RSPAMD_WORKER_SOCKET_UDP) {
  351. fd = rspamd_inet_address_listen (g_ptr_array_index (addrs, i),
  352. SOCK_DGRAM, TRUE);
  353. if (fd != -1) {
  354. ls = g_malloc0 (sizeof (*ls));
  355. ls->addr = rspamd_inet_address_copy (g_ptr_array_index (addrs, i));
  356. ls->fd = fd;
  357. ls->type = RSPAMD_WORKER_SOCKET_UDP;
  358. result = g_list_prepend (result, ls);
  359. }
  360. }
  361. }
  362. return result;
  363. }
  364. static GList *
  365. systemd_get_socket (struct rspamd_main *rspamd_main, gint number)
  366. {
  367. int sock, num_passed, flags;
  368. GList *result = NULL;
  369. const gchar *e;
  370. gchar *err;
  371. struct stat st;
  372. /* XXX: can we trust the current choice ? */
  373. static const int sd_listen_fds_start = 3;
  374. struct rspamd_worker_listen_socket *ls;
  375. union {
  376. struct sockaddr_storage ss;
  377. struct sockaddr sa;
  378. } addr_storage;
  379. socklen_t slen = sizeof (addr_storage);
  380. gint stype;
  381. e = getenv ("LISTEN_FDS");
  382. if (e != NULL) {
  383. errno = 0;
  384. num_passed = strtoul (e, &err, 10);
  385. if ((err == NULL || *err == '\0') && num_passed > number) {
  386. sock = number + sd_listen_fds_start;
  387. if (fstat (sock, &st) == -1) {
  388. msg_warn_main ("cannot stat systemd descriptor %d", sock);
  389. return NULL;
  390. }
  391. if (!S_ISSOCK (st.st_mode)) {
  392. msg_warn_main ("systemd descriptor %d is not a socket", sock);
  393. errno = EINVAL;
  394. return NULL;
  395. }
  396. flags = fcntl (sock, F_GETFD);
  397. if (flags != -1) {
  398. (void)fcntl (sock, F_SETFD, flags | FD_CLOEXEC);
  399. }
  400. rspamd_socket_nonblocking (sock);
  401. if (getsockname (sock, &addr_storage.sa, &slen) == -1) {
  402. msg_warn_main ("cannot get name for systemd descriptor %d: %s",
  403. sock, strerror (errno));
  404. errno = EINVAL;
  405. return NULL;
  406. }
  407. ls = g_malloc0 (sizeof (*ls));
  408. ls->addr = rspamd_inet_address_from_sa (&addr_storage.sa, slen);
  409. ls->fd = sock;
  410. slen = sizeof (stype);
  411. if (getsockopt (sock, SOL_SOCKET, SO_TYPE, &stype, &slen) != -1) {
  412. if (stype == SOCK_STREAM) {
  413. ls->type = RSPAMD_WORKER_SOCKET_TCP;
  414. }
  415. else {
  416. ls->type = RSPAMD_WORKER_SOCKET_UDP;
  417. }
  418. }
  419. else {
  420. msg_warn_main ("cannot get type for systemd descriptor %d: %s",
  421. sock, strerror (errno));
  422. ls->type = RSPAMD_WORKER_SOCKET_TCP;
  423. }
  424. result = g_list_prepend (result, ls);
  425. }
  426. else if (num_passed <= number) {
  427. msg_err_main ("systemd LISTEN_FDS does not contain the expected fd: %d",
  428. num_passed);
  429. errno = EOVERFLOW;
  430. }
  431. }
  432. else {
  433. msg_err_main ("cannot get systemd variable 'LISTEN_FDS'");
  434. errno = ENOENT;
  435. }
  436. return result;
  437. }
  438. static inline uintptr_t
  439. make_listen_key (struct rspamd_worker_bind_conf *cf)
  440. {
  441. rspamd_cryptobox_fast_hash_state_t st;
  442. guint i, keylen = 0;
  443. guint8 *key;
  444. rspamd_inet_addr_t *addr;
  445. guint16 port;
  446. rspamd_cryptobox_fast_hash_init (&st, rspamd_hash_seed ());
  447. if (cf->is_systemd) {
  448. rspamd_cryptobox_fast_hash_update (&st, "systemd", sizeof ("systemd"));
  449. rspamd_cryptobox_fast_hash_update (&st, &cf->cnt, sizeof (cf->cnt));
  450. }
  451. else {
  452. rspamd_cryptobox_fast_hash_update (&st, cf->name, strlen (cf->name));
  453. for (i = 0; i < cf->cnt; i ++) {
  454. addr = g_ptr_array_index (cf->addrs, i);
  455. key = rspamd_inet_address_get_hash_key (
  456. addr, &keylen);
  457. rspamd_cryptobox_fast_hash_update (&st, key, keylen);
  458. port = rspamd_inet_address_get_port (addr);
  459. rspamd_cryptobox_fast_hash_update (&st, &port, sizeof (port));
  460. }
  461. }
  462. return rspamd_cryptobox_fast_hash_final (&st);
  463. }
  464. static void
  465. spawn_worker_type (struct rspamd_main *rspamd_main, struct ev_loop *event_loop,
  466. struct rspamd_worker_conf *cf)
  467. {
  468. gint i;
  469. if (cf->count < 0) {
  470. msg_info_main ("skip spawning of worker %s: disabled in configuration",
  471. cf->worker->name);
  472. return;
  473. }
  474. if (cf->worker->flags & RSPAMD_WORKER_UNIQUE) {
  475. if (cf->count > 1) {
  476. msg_warn_main (
  477. "cannot spawn more than 1 %s worker, so spawn one",
  478. cf->worker->name);
  479. }
  480. rspamd_fork_worker (rspamd_main, cf, 0, event_loop, rspamd_cld_handler);
  481. }
  482. else if (cf->worker->flags & RSPAMD_WORKER_THREADED) {
  483. rspamd_fork_worker (rspamd_main, cf, 0, event_loop, rspamd_cld_handler);
  484. }
  485. else {
  486. for (i = 0; i < cf->count; i++) {
  487. rspamd_fork_worker (rspamd_main, cf, i, event_loop,
  488. rspamd_cld_handler);
  489. }
  490. }
  491. }
  492. static void
  493. spawn_workers (struct rspamd_main *rspamd_main, struct ev_loop *ev_base)
  494. {
  495. GList *cur, *ls;
  496. struct rspamd_worker_conf *cf;
  497. gpointer p;
  498. guintptr key;
  499. struct rspamd_worker_bind_conf *bcf;
  500. gboolean listen_ok = FALSE;
  501. GPtrArray *seen_mandatory_workers;
  502. worker_t **cw, *wrk;
  503. guint i;
  504. /* Special hack for hs_helper if it's not defined in a config */
  505. seen_mandatory_workers = g_ptr_array_new ();
  506. cur = rspamd_main->cfg->workers;
  507. while (cur) {
  508. cf = cur->data;
  509. listen_ok = FALSE;
  510. if (cf->worker == NULL) {
  511. msg_err_main ("type of worker is unspecified, skip spawning");
  512. }
  513. else {
  514. if (!cf->enabled || cf->count <= 0) {
  515. msg_info_main ("worker of type %s(%s) is disabled in the config, "
  516. "skip spawning", g_quark_to_string (cf->type),
  517. cf->bind_conf ? cf->bind_conf->bind_line : "none");
  518. cur = g_list_next (cur);
  519. continue;
  520. }
  521. if (cf->worker->flags & RSPAMD_WORKER_ALWAYS_START) {
  522. g_ptr_array_add (seen_mandatory_workers, cf->worker);
  523. }
  524. if (cf->worker->flags & RSPAMD_WORKER_HAS_SOCKET) {
  525. LL_FOREACH (cf->bind_conf, bcf) {
  526. key = make_listen_key (bcf);
  527. if ((p =
  528. g_hash_table_lookup (listen_sockets,
  529. GINT_TO_POINTER (key))) == NULL) {
  530. if (!bcf->is_systemd) {
  531. /* Create listen socket */
  532. ls = create_listen_socket (bcf->addrs, bcf->cnt,
  533. cf->worker->listen_type);
  534. }
  535. else {
  536. ls = systemd_get_socket (rspamd_main, bcf->cnt);
  537. }
  538. if (ls == NULL) {
  539. msg_err_main ("cannot listen on %s socket %s: %s",
  540. bcf->is_systemd ? "systemd" : "normal",
  541. bcf->name,
  542. strerror (errno));
  543. }
  544. else {
  545. g_hash_table_insert (listen_sockets, (gpointer)key, ls);
  546. listen_ok = TRUE;
  547. }
  548. }
  549. else {
  550. /* We had socket for this type of worker */
  551. ls = p;
  552. listen_ok = TRUE;
  553. }
  554. /* Do not add existing lists as it causes loops */
  555. if (g_list_position (cf->listen_socks, ls) == -1) {
  556. cf->listen_socks = g_list_concat (cf->listen_socks, ls);
  557. }
  558. }
  559. if (listen_ok) {
  560. spawn_worker_type (rspamd_main, ev_base, cf);
  561. }
  562. else {
  563. msg_err_main ("cannot create listen socket for %s at %s",
  564. g_quark_to_string (cf->type), cf->bind_conf->name);
  565. rspamd_hard_terminate (rspamd_main);
  566. g_assert_not_reached ();
  567. }
  568. }
  569. else {
  570. spawn_worker_type (rspamd_main, ev_base, cf);
  571. }
  572. }
  573. cur = g_list_next (cur);
  574. }
  575. for (cw = workers; *cw != NULL; cw ++) {
  576. gboolean seen = FALSE;
  577. wrk = *cw;
  578. if (wrk->flags & RSPAMD_WORKER_ALWAYS_START) {
  579. for (i = 0; i < seen_mandatory_workers->len; i ++) {
  580. if (wrk == g_ptr_array_index (seen_mandatory_workers, i)) {
  581. seen = TRUE;
  582. break;
  583. }
  584. }
  585. if (!seen) {
  586. cf = rspamd_config_new_worker (rspamd_main->cfg, NULL);
  587. cf->count = 1;
  588. cf->worker = wrk;
  589. cf->type = g_quark_from_static_string (wrk->name);
  590. if (cf->worker->worker_init_func) {
  591. cf->ctx = cf->worker->worker_init_func (rspamd_main->cfg);
  592. }
  593. spawn_worker_type (rspamd_main, ev_base, cf);
  594. }
  595. }
  596. }
  597. g_ptr_array_free (seen_mandatory_workers, TRUE);
  598. }
  599. static void
  600. kill_old_workers (gpointer key, gpointer value, gpointer unused)
  601. {
  602. struct rspamd_worker *w = value;
  603. struct rspamd_main *rspamd_main;
  604. rspamd_main = w->srv;
  605. if (!w->wanna_die) {
  606. w->wanna_die = TRUE;
  607. kill (w->pid, SIGUSR2);
  608. ev_io_stop (rspamd_main->event_loop, &w->srv_ev);
  609. msg_info_main ("send signal to worker %P", w->pid);
  610. }
  611. else {
  612. msg_info_main ("do not send signal to worker %P, already sent", w->pid);
  613. }
  614. }
  615. static void
  616. rspamd_worker_wait (struct rspamd_worker *w)
  617. {
  618. struct rspamd_main *rspamd_main;
  619. rspamd_main = w->srv;
  620. if (term_attempts < 0) {
  621. if (w->cf->worker->flags & RSPAMD_WORKER_KILLABLE) {
  622. msg_warn_main ("terminate worker %s(%P) with SIGKILL",
  623. g_quark_to_string (w->type), w->pid);
  624. if (kill (w->pid, SIGKILL) == -1) {
  625. if (errno == ESRCH) {
  626. /* We have actually killed the process */
  627. return;
  628. }
  629. }
  630. }
  631. else {
  632. if (term_attempts > -(TERMINATION_ATTEMPTS * 2)) {
  633. if (term_attempts % 10 == 0) {
  634. msg_info_main ("waiting for worker %s(%P) to sync, "
  635. "%d seconds remain",
  636. g_quark_to_string (w->type), w->pid,
  637. (TERMINATION_ATTEMPTS * 2 + term_attempts) / 5);
  638. kill (w->pid, SIGTERM);
  639. if (errno == ESRCH) {
  640. /* We have actually killed the process */
  641. return;
  642. }
  643. }
  644. }
  645. else {
  646. msg_err_main ("data corruption warning: terminating "
  647. "special worker %s(%P) with SIGKILL",
  648. g_quark_to_string (w->type), w->pid);
  649. kill (w->pid, SIGKILL);
  650. if (errno == ESRCH) {
  651. /* We have actually killed the process */
  652. return;
  653. }
  654. }
  655. }
  656. }
  657. }
  658. static void
  659. hash_worker_wait_callback (gpointer key, gpointer value, gpointer unused)
  660. {
  661. rspamd_worker_wait ((struct rspamd_worker *)value);
  662. }
  663. struct core_check_cbdata {
  664. struct rspamd_config *cfg;
  665. gsize total_count;
  666. gsize total_size;
  667. };
  668. #ifdef HAVE_NFTW
  669. static struct core_check_cbdata cores_cbdata;
  670. static gint
  671. rspamd_check_core_cb (const gchar *path, const struct stat *st,
  672. gint flag, struct FTW *ft)
  673. {
  674. if (S_ISREG (st->st_mode)) {
  675. cores_cbdata.total_count ++;
  676. /* Use physical size instead of displayed one */
  677. cores_cbdata.total_size += st->st_blocks * 512;
  678. }
  679. return 0;
  680. }
  681. #endif
  682. static void
  683. rspamd_check_core_limits (struct rspamd_main *rspamd_main)
  684. {
  685. #ifdef HAVE_NFTW
  686. struct rspamd_config *cfg = rspamd_main->cfg;
  687. cores_cbdata.cfg = cfg;
  688. cores_cbdata.total_count = 0;
  689. cores_cbdata.total_size = 0;
  690. if (cfg->cores_dir && (cfg->max_cores_count || cfg->max_cores_size)) {
  691. if (nftw (cfg->cores_dir, rspamd_check_core_cb, 1, FTW_MOUNT|FTW_PHYS)
  692. == -1) {
  693. msg_err_main ("nftw failed for path %s: %s", cfg->cores_dir,
  694. strerror (errno));
  695. }
  696. else {
  697. if (!rspamd_main->cores_throttling) {
  698. if (cfg->max_cores_size &&
  699. cores_cbdata.total_size > cfg->max_cores_size) {
  700. msg_warn_main (
  701. "enable cores throttling as size of cores in"
  702. " %s is %Hz, limit is %Hz",
  703. cfg->cores_dir,
  704. cores_cbdata.total_size,
  705. cfg->max_cores_size);
  706. rspamd_main->cores_throttling = TRUE;
  707. }
  708. if (cfg->max_cores_count &&
  709. cores_cbdata.total_count > cfg->max_cores_count) {
  710. msg_warn_main (
  711. "enable cores throttling as count of cores in"
  712. " %s is %z, limit is %z",
  713. cfg->cores_dir,
  714. cores_cbdata.total_count,
  715. cfg->max_cores_count);
  716. rspamd_main->cores_throttling = TRUE;
  717. }
  718. }
  719. else {
  720. if (cfg->max_cores_size &&
  721. cores_cbdata.total_size < cfg->max_cores_size) {
  722. msg_info_main (
  723. "disable cores throttling as size of cores in"
  724. " %s is now %Hz, limit is %Hz",
  725. cfg->cores_dir,
  726. cores_cbdata.total_size,
  727. cfg->max_cores_size);
  728. rspamd_main->cores_throttling = FALSE;
  729. }
  730. if (cfg->max_cores_count &&
  731. cores_cbdata.total_count < cfg->max_cores_count) {
  732. msg_info_main (
  733. "disable cores throttling as count of cores in"
  734. " %s is %z, limit is %z",
  735. cfg->cores_dir,
  736. cores_cbdata.total_count,
  737. cfg->max_cores_count);
  738. rspamd_main->cores_throttling = FALSE;
  739. }
  740. }
  741. }
  742. }
  743. #endif
  744. }
  745. static void
  746. reopen_log_handler (gpointer key, gpointer value, gpointer unused)
  747. {
  748. struct rspamd_worker *w = value;
  749. struct rspamd_main *rspamd_main;
  750. rspamd_main = w->srv;
  751. if (kill (w->pid, SIGUSR1) == -1) {
  752. msg_err_main ("kill failed for pid %P: %s", w->pid, strerror (errno));
  753. }
  754. }
  755. static gboolean
  756. load_rspamd_config (struct rspamd_main *rspamd_main,
  757. struct rspamd_config *cfg, gboolean init_modules,
  758. enum rspamd_post_load_options opts,
  759. gboolean reload)
  760. {
  761. cfg->compiled_modules = modules;
  762. cfg->compiled_workers = workers;
  763. if (!rspamd_config_read (cfg, cfg->cfg_name, config_logger, rspamd_main,
  764. ucl_vars, skip_template, lua_env)) {
  765. return FALSE;
  766. }
  767. /* Strictly set temp dir */
  768. if (!cfg->temp_dir) {
  769. msg_warn_main ("tempdir is not set, trying to use $TMPDIR");
  770. cfg->temp_dir =
  771. rspamd_mempool_strdup (cfg->cfg_pool, getenv ("TMPDIR"));
  772. if (!cfg->temp_dir) {
  773. msg_warn_main ("$TMPDIR is empty too, using /tmp as default");
  774. cfg->temp_dir = rspamd_mempool_strdup (cfg->cfg_pool, "/tmp");
  775. }
  776. }
  777. if (!reload) {
  778. /*
  779. * As some rules are defined in lua, we need to process them, then init
  780. * modules and merely afterwards to init modules
  781. */
  782. rspamd_lua_post_load_config (cfg);
  783. if (init_modules) {
  784. rspamd_init_filters (cfg, reload);
  785. }
  786. /* Do post-load actions */
  787. rspamd_config_post_load (cfg, opts);
  788. }
  789. return TRUE;
  790. }
  791. static void
  792. stop_srv_ev (gpointer key, gpointer value, gpointer ud)
  793. {
  794. struct rspamd_worker *cur = (struct rspamd_worker *)value;
  795. struct rspamd_main *rspamd_main = (struct rspamd_main *)ud;
  796. ev_io_stop (rspamd_main->event_loop, &cur->srv_ev);
  797. }
  798. static void
  799. rspamd_final_timer_handler (EV_P_ ev_timer *w, int revents)
  800. {
  801. struct rspamd_main *rspamd_main = (struct rspamd_main *)w->data;
  802. term_attempts--;
  803. g_hash_table_foreach (rspamd_main->workers, hash_worker_wait_callback, NULL);
  804. if (g_hash_table_size (rspamd_main->workers) == 0) {
  805. ev_break (rspamd_main->event_loop, EVBREAK_ALL);
  806. }
  807. }
  808. /* Signal handlers */
  809. static void
  810. rspamd_term_handler (struct ev_loop *loop, ev_signal *w, int revents)
  811. {
  812. struct rspamd_main *rspamd_main = (struct rspamd_main *)w->data;
  813. static ev_timer ev_finale;
  814. if (!rspamd_main->wanna_die) {
  815. rspamd_main->wanna_die = TRUE;
  816. msg_info_main ("catch termination signal, waiting for children");
  817. rspamd_log_nolock (rspamd_main->logger);
  818. /* Stop srv events to avoid false notifications */
  819. g_hash_table_foreach (rspamd_main->workers, stop_srv_ev, rspamd_main);
  820. rspamd_pass_signal (rspamd_main->workers, SIGTERM);
  821. if (control_fd != -1) {
  822. ev_io_stop (rspamd_main->event_loop, &control_ev);
  823. close (control_fd);
  824. }
  825. if (valgrind_mode) {
  826. /* Special case if we are likely running with valgrind */
  827. term_attempts = TERMINATION_ATTEMPTS * 10;
  828. }
  829. else {
  830. term_attempts = TERMINATION_ATTEMPTS;
  831. }
  832. ev_finale.data = rspamd_main;
  833. ev_timer_init (&ev_finale, rspamd_final_timer_handler, 0.2, 0.2);
  834. ev_timer_start (rspamd_main->event_loop, &ev_finale);
  835. }
  836. }
  837. static void
  838. rspamd_usr1_handler (struct ev_loop *loop, ev_signal *w, int revents)
  839. {
  840. struct rspamd_main *rspamd_main = (struct rspamd_main *)w->data;
  841. if (!rspamd_main->wanna_die) {
  842. rspamd_log_reopen_priv (rspamd_main->logger,
  843. rspamd_main->workers_uid,
  844. rspamd_main->workers_gid);
  845. g_hash_table_foreach (rspamd_main->workers, reopen_log_handler,
  846. NULL);
  847. }
  848. }
  849. static void
  850. rspamd_hup_handler (struct ev_loop *loop, ev_signal *w, int revents)
  851. {
  852. struct rspamd_main *rspamd_main = (struct rspamd_main *)w->data;
  853. if (!rspamd_main->wanna_die) {
  854. msg_info_main ("rspamd "
  855. RVERSION
  856. " is restarting");
  857. g_hash_table_foreach (rspamd_main->workers, kill_old_workers, NULL);
  858. rspamd_log_close_priv (rspamd_main->logger,
  859. FALSE,
  860. rspamd_main->workers_uid,
  861. rspamd_main->workers_gid);
  862. reread_config (rspamd_main);
  863. rspamd_check_core_limits (rspamd_main);
  864. spawn_workers (rspamd_main, rspamd_main->event_loop);
  865. }
  866. }
  867. /* Called when a dead child has been found */
  868. static void
  869. rspamd_cld_handler (EV_P_ ev_child *w, struct rspamd_main *rspamd_main,
  870. struct rspamd_worker *wrk)
  871. {
  872. gboolean need_refork;
  873. /* Turn off locking for logger */
  874. ev_child_stop (EV_A_ w);
  875. rspamd_log_nolock (rspamd_main->logger);
  876. /* Remove dead child form children list */
  877. g_hash_table_remove (rspamd_main->workers, GSIZE_TO_POINTER (wrk->pid));
  878. if (wrk->srv_pipe[0] != -1) {
  879. /* Ugly workaround */
  880. if (wrk->tmp_data) {
  881. g_free (wrk->tmp_data);
  882. }
  883. ev_io_stop (rspamd_main->event_loop, &wrk->srv_ev);
  884. }
  885. if (wrk->control_pipe[0] != -1) {
  886. /* We also need to clean descriptors left */
  887. close (wrk->control_pipe[0]);
  888. close (wrk->srv_pipe[0]);
  889. }
  890. REF_RELEASE (wrk->cf);
  891. if (wrk->finish_actions) {
  892. g_ptr_array_free (wrk->finish_actions, TRUE);
  893. }
  894. need_refork = rspamd_check_termination_clause (wrk->srv, wrk, w->rstatus);
  895. if (need_refork) {
  896. /* Fork another worker in replace of dead one */
  897. msg_info_main ("respawn process %s in lieu of terminated process with pid %P",
  898. g_quark_to_string (wrk->type),
  899. wrk->pid);
  900. rspamd_check_core_limits (rspamd_main);
  901. rspamd_fork_delayed (wrk->cf, wrk->index, rspamd_main);
  902. rspamd_log_lock (rspamd_main->logger);
  903. }
  904. else {
  905. msg_info_main ("do not respawn process %s after found terminated process with pid %P",
  906. g_quark_to_string (wrk->type),
  907. wrk->pid);
  908. }
  909. g_free (wrk);
  910. }
  911. /* Control socket handler */
  912. static void
  913. rspamd_control_handler (EV_P_ ev_io *w, int revents)
  914. {
  915. struct rspamd_main *rspamd_main = (struct rspamd_main *)w->data;
  916. rspamd_inet_addr_t *addr;
  917. gint nfd;
  918. if ((nfd =
  919. rspamd_accept_from_socket (w->fd, &addr, NULL, NULL)) == -1) {
  920. msg_warn_main ("accept failed: %s", strerror (errno));
  921. return;
  922. }
  923. /* Check for EAGAIN */
  924. if (nfd == 0) {
  925. return;
  926. }
  927. msg_info_main ("accepted control connection from %s",
  928. rspamd_inet_address_to_string (addr));
  929. rspamd_control_process_client_socket (rspamd_main, nfd, addr);
  930. }
  931. static guint
  932. rspamd_spair_hash (gconstpointer p)
  933. {
  934. return rspamd_cryptobox_fast_hash (p, PAIR_ID_LEN, rspamd_hash_seed ());
  935. }
  936. static gboolean
  937. rspamd_spair_equal (gconstpointer a, gconstpointer b)
  938. {
  939. return memcmp (a, b, PAIR_ID_LEN) == 0;
  940. }
  941. static void
  942. rspamd_spair_close (gpointer p)
  943. {
  944. gint *fds = p;
  945. close (fds[0]);
  946. close (fds[1]);
  947. g_free (p);
  948. }
  949. static void
  950. version (void)
  951. {
  952. #if defined(GIT_VERSION) && GIT_VERSION == 1
  953. rspamd_printf ("Rspamd daemon version " RVERSION "-git." RID "\n");
  954. #else
  955. rspamd_printf ("Rspamd daemon version " RVERSION "\n");
  956. #endif
  957. }
  958. gint
  959. main (gint argc, gchar **argv, gchar **env)
  960. {
  961. gint i, res = 0;
  962. struct sigaction signals, sigpipe_act;
  963. worker_t **pworker;
  964. GQuark type;
  965. rspamd_inet_addr_t *control_addr = NULL;
  966. struct ev_loop *event_loop;
  967. struct rspamd_main *rspamd_main;
  968. gboolean skip_pid = FALSE;
  969. rspamd_main = (struct rspamd_main *) g_malloc0 (sizeof (struct rspamd_main));
  970. rspamd_main->server_pool = rspamd_mempool_new (rspamd_mempool_suggest_size (),
  971. "main");
  972. rspamd_main->stat = rspamd_mempool_alloc0_shared (rspamd_main->server_pool,
  973. sizeof (struct rspamd_stat));
  974. rspamd_main->cfg = rspamd_config_new (RSPAMD_CONFIG_INIT_DEFAULT);
  975. rspamd_main->spairs = g_hash_table_new_full (rspamd_spair_hash,
  976. rspamd_spair_equal, g_free, rspamd_spair_close);
  977. rspamd_main->start_mtx = rspamd_mempool_get_mutex (rspamd_main->server_pool);
  978. if (getenv ("VALGRIND") != NULL) {
  979. valgrind_mode = TRUE;
  980. }
  981. #ifndef HAVE_SETPROCTITLE
  982. init_title (rspamd_main, argc, argv, env);
  983. #endif
  984. rspamd_main->cfg->libs_ctx = rspamd_init_libs ();
  985. memset (&signals, 0, sizeof (struct sigaction));
  986. read_cmd_line (&argc, &argv, rspamd_main->cfg);
  987. if (show_version) {
  988. version ();
  989. exit (EXIT_SUCCESS);
  990. }
  991. if (argc > 0) {
  992. /* Parse variables */
  993. for (i = 0; i < argc; i++) {
  994. if (strchr (argv[i], '=') != NULL) {
  995. gchar *k, *v, *t;
  996. k = g_strdup (argv[i]);
  997. t = strchr (k, '=');
  998. v = g_strdup (t + 1);
  999. *t = '\0';
  1000. if (ucl_vars == NULL) {
  1001. ucl_vars = g_hash_table_new_full (rspamd_strcase_hash,
  1002. rspamd_strcase_equal, g_free, g_free);
  1003. }
  1004. g_hash_table_insert (ucl_vars, k, v);
  1005. }
  1006. }
  1007. }
  1008. if (is_debug) {
  1009. rspamd_main->cfg->log_level = G_LOG_LEVEL_DEBUG;
  1010. }
  1011. else {
  1012. rspamd_main->cfg->log_level = G_LOG_LEVEL_MESSAGE;
  1013. }
  1014. type = g_quark_from_static_string ("main");
  1015. /* First set logger to console logger */
  1016. rspamd_main->cfg->log_type = RSPAMD_LOG_CONSOLE;
  1017. rspamd_set_logger (rspamd_main->cfg, type,
  1018. &rspamd_main->logger, rspamd_main->server_pool);
  1019. (void) rspamd_log_open (rspamd_main->logger);
  1020. g_log_set_default_handler (rspamd_glib_log_function, rspamd_main->logger);
  1021. g_set_printerr_handler (rspamd_glib_printerr_function);
  1022. detect_priv (rspamd_main);
  1023. pworker = &workers[0];
  1024. while (*pworker) {
  1025. /* Init string quarks */
  1026. (void) g_quark_from_static_string ((*pworker)->name);
  1027. pworker++;
  1028. }
  1029. /* Init listen sockets hash */
  1030. listen_sockets = g_hash_table_new (g_direct_hash, g_direct_equal);
  1031. rspamd_log_close_priv (rspamd_main->logger, FALSE,
  1032. rspamd_main->workers_uid, rspamd_main->workers_gid);
  1033. sqlite3_initialize ();
  1034. /* Load config */
  1035. if (!load_rspamd_config (rspamd_main, rspamd_main->cfg, TRUE,
  1036. RSPAMD_CONFIG_LOAD_ALL, FALSE)) {
  1037. exit (EXIT_FAILURE);
  1038. }
  1039. /* Override pidfile from configuration by command line argument */
  1040. if (rspamd_pidfile != NULL) {
  1041. rspamd_main->cfg->pid_file = rspamd_pidfile;
  1042. }
  1043. /* Force debug log */
  1044. if (is_debug) {
  1045. rspamd_main->cfg->log_level = G_LOG_LEVEL_DEBUG;
  1046. }
  1047. /* Create rolling history */
  1048. rspamd_main->history = rspamd_roll_history_new (rspamd_main->server_pool,
  1049. rspamd_main->cfg->history_rows, rspamd_main->cfg);
  1050. gperf_profiler_init (rspamd_main->cfg, "main");
  1051. msg_info_main ("rspamd "
  1052. RVERSION
  1053. " is starting, build id: "
  1054. RID);
  1055. rspamd_main->cfg->cfg_name = rspamd_mempool_strdup (
  1056. rspamd_main->cfg->cfg_pool,
  1057. rspamd_main->cfg->cfg_name);
  1058. msg_info_main ("cpu features: %s",
  1059. rspamd_main->cfg->libs_ctx->crypto_ctx->cpu_extensions);
  1060. msg_info_main ("cryptobox configuration: curve25519(libsodium), "
  1061. "chacha20(%s), poly1305(libsodium), siphash(libsodium), blake2(libsodium), base64(%s)",
  1062. rspamd_main->cfg->libs_ctx->crypto_ctx->chacha20_impl,
  1063. rspamd_main->cfg->libs_ctx->crypto_ctx->base64_impl);
  1064. msg_info_main ("libottery prf: %s", ottery_get_impl_name ());
  1065. /* Daemonize */
  1066. if (!no_fork && daemon (0, 0) == -1) {
  1067. rspamd_fprintf (stderr, "Cannot daemonize\n");
  1068. exit (-errno);
  1069. }
  1070. /* Write info */
  1071. rspamd_main->pid = getpid ();
  1072. rspamd_main->type = type;
  1073. if (!valgrind_mode) {
  1074. rspamd_set_crash_handler (rspamd_main);
  1075. }
  1076. /* Ignore SIGPIPE as we handle write errors manually */
  1077. sigemptyset (&sigpipe_act.sa_mask);
  1078. sigaddset (&sigpipe_act.sa_mask, SIGPIPE);
  1079. sigpipe_act.sa_handler = SIG_IGN;
  1080. sigpipe_act.sa_flags = 0;
  1081. sigaction (SIGPIPE, &sigpipe_act, NULL);
  1082. if (rspamd_main->cfg->pid_file == NULL) {
  1083. msg_info_main ("pid file is not specified, skipping writing it");
  1084. skip_pid = TRUE;
  1085. }
  1086. else if (no_fork) {
  1087. msg_info_main ("skip writing pid in no-fork mode");
  1088. skip_pid = TRUE;
  1089. }
  1090. else if (rspamd_write_pid (rspamd_main) == -1) {
  1091. msg_err_main ("cannot write pid file %s", rspamd_main->cfg->pid_file);
  1092. exit (-errno);
  1093. }
  1094. /* Block signals to use sigsuspend in future */
  1095. sigprocmask (SIG_BLOCK, &signals.sa_mask, NULL);
  1096. /* Set title */
  1097. setproctitle ("main process");
  1098. /* Flush log */
  1099. rspamd_log_flush (rspamd_main->logger);
  1100. /* Open control socket if needed */
  1101. control_fd = -1;
  1102. if (rspamd_main->cfg->control_socket_path) {
  1103. if (!rspamd_parse_inet_address (&control_addr,
  1104. rspamd_main->cfg->control_socket_path,
  1105. 0)) {
  1106. msg_err_main ("cannot parse inet address %s",
  1107. rspamd_main->cfg->control_socket_path);
  1108. }
  1109. else {
  1110. control_fd = rspamd_inet_address_listen (control_addr, SOCK_STREAM,
  1111. TRUE);
  1112. if (control_fd == -1) {
  1113. msg_err_main ("cannot open control socket at path: %s",
  1114. rspamd_main->cfg->control_socket_path);
  1115. }
  1116. }
  1117. }
  1118. /* Maybe read roll history */
  1119. if (rspamd_main->cfg->history_file) {
  1120. rspamd_roll_history_load (rspamd_main->history,
  1121. rspamd_main->cfg->history_file);
  1122. }
  1123. #if defined(WITH_GPERF_TOOLS)
  1124. ProfilerStop ();
  1125. #endif
  1126. /* Spawn workers */
  1127. rspamd_main->workers = g_hash_table_new (g_direct_hash, g_direct_equal);
  1128. /* Init event base */
  1129. event_loop = ev_default_loop (EVFLAG_SIGNALFD|EVBACKEND_ALL);
  1130. rspamd_main->event_loop = event_loop;
  1131. if (event_loop) {
  1132. unsigned loop_type = ev_backend (event_loop);
  1133. const gchar *loop_str = "unknown";
  1134. gboolean poor_backend = TRUE;
  1135. switch (loop_type) {
  1136. case EVBACKEND_EPOLL:
  1137. loop_str = "epoll";
  1138. poor_backend = FALSE;
  1139. break;
  1140. case EVBACKEND_POLL:
  1141. loop_str = "poll";
  1142. break;
  1143. case EVBACKEND_SELECT:
  1144. loop_str = "select";
  1145. break;
  1146. case EVBACKEND_KQUEUE:
  1147. loop_str = "kqueue";
  1148. poor_backend = FALSE;
  1149. break;
  1150. case EVBACKEND_PORT:
  1151. loop_str = "port";
  1152. poor_backend = FALSE;
  1153. break;
  1154. case EVBACKEND_DEVPOLL:
  1155. loop_str = "/dev/poll";
  1156. poor_backend = FALSE;
  1157. break;
  1158. default:
  1159. break;
  1160. }
  1161. if (poor_backend) {
  1162. msg_warn_main ("event loop uses non-optimal backend: %s", loop_str);
  1163. }
  1164. else {
  1165. msg_info_main ("event loop initialised with backend: %s", loop_str);
  1166. }
  1167. }
  1168. else {
  1169. msg_err ("cannot init event loop! exiting");
  1170. exit (EXIT_FAILURE);
  1171. }
  1172. /* Unblock signals */
  1173. sigemptyset (&signals.sa_mask);
  1174. sigprocmask (SIG_SETMASK, &signals.sa_mask, NULL);
  1175. /* Set events for signals */
  1176. ev_signal_init (&rspamd_main->term_ev, rspamd_term_handler, SIGTERM);
  1177. rspamd_main->term_ev.data = rspamd_main;
  1178. ev_signal_start (event_loop, &rspamd_main->term_ev);
  1179. ev_signal_init (&rspamd_main->int_ev, rspamd_term_handler, SIGINT);
  1180. rspamd_main->int_ev.data = rspamd_main;
  1181. ev_signal_start (event_loop, &rspamd_main->int_ev);
  1182. ev_signal_init (&rspamd_main->hup_ev, rspamd_hup_handler, SIGHUP);
  1183. rspamd_main->hup_ev.data = rspamd_main;
  1184. ev_signal_start (event_loop, &rspamd_main->hup_ev);
  1185. ev_signal_init (&rspamd_main->usr1_ev, rspamd_usr1_handler, SIGUSR1);
  1186. rspamd_main->usr1_ev.data = rspamd_main;
  1187. ev_signal_start (event_loop, &rspamd_main->usr1_ev);
  1188. rspamd_check_core_limits (rspamd_main);
  1189. rspamd_mempool_lock_mutex (rspamd_main->start_mtx);
  1190. spawn_workers (rspamd_main, event_loop);
  1191. rspamd_mempool_unlock_mutex (rspamd_main->start_mtx);
  1192. rspamd_main->http_ctx = rspamd_http_context_create (rspamd_main->cfg,
  1193. event_loop, rspamd_main->cfg->ups_ctx);
  1194. if (control_fd != -1) {
  1195. msg_info_main ("listening for control commands on %s",
  1196. rspamd_inet_address_to_string (control_addr));
  1197. ev_io_init (&control_ev, rspamd_control_handler, control_fd, EV_READ);
  1198. control_ev.data = rspamd_main;
  1199. ev_io_start (event_loop, &control_ev);
  1200. }
  1201. ev_loop (event_loop, 0);
  1202. /* Maybe save roll history */
  1203. if (rspamd_main->cfg->history_file) {
  1204. rspamd_roll_history_save (rspamd_main->history,
  1205. rspamd_main->cfg->history_file);
  1206. }
  1207. msg_info_main ("terminating...");
  1208. REF_RELEASE (rspamd_main->cfg);
  1209. rspamd_log_close (rspamd_main->logger, TRUE);
  1210. g_hash_table_unref (rspamd_main->spairs);
  1211. g_hash_table_unref (rspamd_main->workers);
  1212. rspamd_mempool_delete (rspamd_main->server_pool);
  1213. if (!skip_pid) {
  1214. rspamd_pidfile_close (rspamd_main->pfh);
  1215. }
  1216. g_free (rspamd_main);
  1217. ev_unref (event_loop);
  1218. sqlite3_shutdown ();
  1219. if (control_addr) {
  1220. rspamd_inet_address_free (control_addr);
  1221. }
  1222. return (res);
  1223. }