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 40KB

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