]> source.dussan.org Git - rspamd.git/commitdiff
[Minor] Close sockets that do not belong to a current worker
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 9 Jun 2020 11:55:20 +0000 (12:55 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 9 Jun 2020 11:55:20 +0000 (12:55 +0100)
src/libserver/worker_util.c
src/libserver/worker_util.h
src/rspamd.c

index e0d7d6bc7b3f25883a9a0348e3a133b4039d08d3..50f81fd7bfd00af8efcfd641516d669f61c0396e 100644 (file)
@@ -933,16 +933,136 @@ rspamd_main_heartbeat_start (struct rspamd_worker *wrk, struct ev_loop *event_lo
        ev_timer_start (event_loop, &wrk->hb.heartbeat_ev);
 }
 
+/**
+ * Handles worker after fork returned zero
+ * @param wrk
+ * @param rspamd_main
+ * @param cf
+ * @param listen_sockets
+ */
+static void
+rspamd_handle_child_fork (struct rspamd_worker *wrk,
+                                                 struct rspamd_main *rspamd_main,
+                                                 struct rspamd_worker_conf *cf,
+                                                 GHashTable *listen_sockets)
+{
+       gint rc;
+       struct rlimit rlim;
+
+       /* Update pid for logging */
+       rspamd_log_on_fork (cf->type, rspamd_main->cfg, rspamd_main->logger);
+       wrk->pid = getpid ();
+
+       /* Init PRNG after fork */
+       rc = ottery_init (rspamd_main->cfg->libs_ctx->ottery_cfg);
+       if (rc != OTTERY_ERR_NONE) {
+               msg_err_main ("cannot initialize PRNG: %d", rc);
+               abort ();
+       }
+
+       rspamd_random_seed_fast ();
+#ifdef HAVE_EVUTIL_RNG_INIT
+       evutil_secure_rng_init ();
+#endif
+
+       /*
+        * Libev stores all signals in a global table, so
+        * previous handlers must be explicitly detached and forgotten
+        * before starting a new loop
+        */
+       ev_signal_stop (rspamd_main->event_loop, &rspamd_main->int_ev);
+       ev_signal_stop (rspamd_main->event_loop, &rspamd_main->term_ev);
+       ev_signal_stop (rspamd_main->event_loop, &rspamd_main->hup_ev);
+       ev_signal_stop (rspamd_main->event_loop, &rspamd_main->usr1_ev);
+       /* Remove the inherited event base */
+       ev_loop_destroy (rspamd_main->event_loop);
+       rspamd_main->event_loop = NULL;
+
+       /* Close unused sockets */
+       GHashTableIter it;
+       gpointer k, v;
+
+
+       g_hash_table_iter_init (&it, listen_sockets);
+
+       while (g_hash_table_iter_next (&it, &k, &v)) {
+               GList *elt = (GList *)v;
+               GList *our = cf->listen_socks;
+
+               if (our != elt) {
+                       GList *cur = elt;
+
+                       while (cur) {
+                               struct rspamd_worker_listen_socket *ls =
+                                               (struct rspamd_worker_listen_socket *)cur->data;
+
+                               if (close (ls->fd) == -1) {
+                                       msg_err ("cannot close fd %d: %s", ls->fd, strerror (errno));
+                               }
+
+                               cur = g_list_next (cur);
+                       }
+               }
+       }
+
+       /* Drop privileges */
+       rspamd_worker_drop_priv (rspamd_main);
+       /* Set limits */
+       rspamd_worker_set_limits (rspamd_main, cf);
+       /* Re-set stack limit */
+       getrlimit (RLIMIT_STACK, &rlim);
+       rlim.rlim_cur = 100 * 1024 * 1024;
+       rlim.rlim_max = rlim.rlim_cur;
+       setrlimit (RLIMIT_STACK, &rlim);
+
+       if (cf->bind_conf) {
+               setproctitle ("%s process (%s)", cf->worker->name,
+                               cf->bind_conf->bind_line);
+       }
+       else {
+               setproctitle ("%s process", cf->worker->name);
+       }
+
+       if (rspamd_main->pfh) {
+               rspamd_pidfile_close (rspamd_main->pfh);
+       }
+
+       if (rspamd_main->cfg->log_silent_workers) {
+               rspamd_log_set_log_level (rspamd_main->logger, G_LOG_LEVEL_MESSAGE);
+       }
+
+       wrk->start_time = rspamd_get_calendar_ticks ();
+
+       if (cf->bind_conf) {
+               msg_info_main ("starting %s process %P (%d); listen on: %s",
+                               cf->worker->name,
+                               getpid (), index, cf->bind_conf->bind_line);
+       }
+       else {
+               msg_info_main ("starting %s process %P (%d)", cf->worker->name,
+                               getpid (), index);
+       }
+       /* Close parent part of socketpair */
+       close (wrk->control_pipe[0]);
+       close (wrk->srv_pipe[0]);
+       rspamd_socket_nonblocking (wrk->control_pipe[1]);
+       rspamd_socket_nonblocking (wrk->srv_pipe[1]);
+       rspamd_main->cfg->cur_worker = wrk;
+       /* Execute worker (this function should not return normally!) */
+       cf->worker->worker_start_func (wrk);
+       /* To distinguish from normal termination */
+       exit (EXIT_FAILURE);
+}
+
 struct rspamd_worker *
 rspamd_fork_worker (struct rspamd_main *rspamd_main,
                                        struct rspamd_worker_conf *cf,
                                        guint index,
                                        struct ev_loop *ev_base,
-                                       rspamd_worker_term_cb term_handler)
+                                       rspamd_worker_term_cb term_handler,
+                                       GHashTable *listen_sockets)
 {
        struct rspamd_worker *wrk;
-       gint rc;
-       struct rlimit rlim;
 
        /* Starting worker process */
        wrk = (struct rspamd_worker *) g_malloc0 (sizeof (struct rspamd_worker));
@@ -984,81 +1104,7 @@ rspamd_fork_worker (struct rspamd_main *rspamd_main,
 
        switch (wrk->pid) {
        case 0:
-               /* Update pid for logging */
-               rspamd_log_on_fork (cf->type, rspamd_main->cfg, rspamd_main->logger);
-               wrk->pid = getpid ();
-
-               /* Init PRNG after fork */
-               rc = ottery_init (rspamd_main->cfg->libs_ctx->ottery_cfg);
-               if (rc != OTTERY_ERR_NONE) {
-                       msg_err_main ("cannot initialize PRNG: %d", rc);
-                       abort ();
-               }
-
-               rspamd_random_seed_fast ();
-#ifdef HAVE_EVUTIL_RNG_INIT
-               evutil_secure_rng_init ();
-#endif
-
-               /*
-                * Libev stores all signals in a global table, so
-                * previous handlers must be explicitly detached and forgotten
-                * before starting a new loop
-                */
-               ev_signal_stop (rspamd_main->event_loop, &rspamd_main->int_ev);
-               ev_signal_stop (rspamd_main->event_loop, &rspamd_main->term_ev);
-               ev_signal_stop (rspamd_main->event_loop, &rspamd_main->hup_ev);
-               ev_signal_stop (rspamd_main->event_loop, &rspamd_main->usr1_ev);
-               /* Remove the inherited event base */
-               ev_loop_destroy (rspamd_main->event_loop);
-               rspamd_main->event_loop = NULL;
-               /* Drop privileges */
-               rspamd_worker_drop_priv (rspamd_main);
-               /* Set limits */
-               rspamd_worker_set_limits (rspamd_main, cf);
-               /* Re-set stack limit */
-               getrlimit (RLIMIT_STACK, &rlim);
-               rlim.rlim_cur = 100 * 1024 * 1024;
-               rlim.rlim_max = rlim.rlim_cur;
-               setrlimit (RLIMIT_STACK, &rlim);
-
-               if (cf->bind_conf) {
-                       setproctitle ("%s process (%s)", cf->worker->name,
-                                       cf->bind_conf->bind_line);
-               }
-               else {
-                       setproctitle ("%s process", cf->worker->name);
-               }
-
-               if (rspamd_main->pfh) {
-                       rspamd_pidfile_close (rspamd_main->pfh);
-               }
-
-               if (rspamd_main->cfg->log_silent_workers) {
-                       rspamd_log_set_log_level (rspamd_main->logger, G_LOG_LEVEL_MESSAGE);
-               }
-
-               wrk->start_time = rspamd_get_calendar_ticks ();
-
-               if (cf->bind_conf) {
-                       msg_info_main ("starting %s process %P (%d); listen on: %s",
-                                       cf->worker->name,
-                                       getpid (), index, cf->bind_conf->bind_line);
-               }
-               else {
-                       msg_info_main ("starting %s process %P (%d)", cf->worker->name,
-                                       getpid (), index);
-               }
-               /* Close parent part of socketpair */
-               close (wrk->control_pipe[0]);
-               close (wrk->srv_pipe[0]);
-               rspamd_socket_nonblocking (wrk->control_pipe[1]);
-               rspamd_socket_nonblocking (wrk->srv_pipe[1]);
-               rspamd_main->cfg->cur_worker = wrk;
-               /* Execute worker (this function should not return normally!) */
-               cf->worker->worker_start_func (wrk);
-               /* To distinguish from normal termination */
-               exit (EXIT_FAILURE);
+               rspamd_handle_child_fork (wrk, rspamd_main, cf, listen_sockets);
                break;
        case -1:
                msg_err_main ("cannot fork main process: %s", strerror (errno));
index 0e9e60545db1ff3e6df4e44e99305785bd1092f2..c20108488c29e9a9806024f99820c398d89d7458 100644 (file)
@@ -202,7 +202,8 @@ void rspamd_worker_session_cache_remove (void *cache, void *ptr);
 struct rspamd_worker *rspamd_fork_worker (struct rspamd_main *,
                                                                                  struct rspamd_worker_conf *, guint idx,
                                                                                  struct ev_loop *ev_base,
-                                                                                 rspamd_worker_term_cb term_handler);
+                                                                                 rspamd_worker_term_cb term_handler,
+                                                                                 GHashTable *listen_sockets);
 
 /**
  * Sets crash signals handlers if compiled with libunwind
index dd47956a2c07f50c22e3dd7ac6c124bcfc729965..ff9ecfa88956dc9fc699370b1347e75836713dff 100644 (file)
@@ -373,7 +373,7 @@ rspamd_fork_delayed_cb (EV_P_ ev_timer *w, int revents)
        rspamd_fork_worker (waiting_worker->rspamd_main, waiting_worker->cf,
                        waiting_worker->oldindex,
                        waiting_worker->rspamd_main->event_loop,
-                       rspamd_cld_handler);
+                       rspamd_cld_handler, listen_sockets);
        REF_RELEASE (waiting_worker->cf);
        g_free (waiting_worker);
 }
@@ -612,15 +612,17 @@ spawn_worker_type (struct rspamd_main *rspamd_main, struct ev_loop *event_loop,
                                        "cannot spawn more than 1 %s worker, so spawn one",
                                        cf->worker->name);
                }
-               rspamd_fork_worker (rspamd_main, cf, 0, event_loop, rspamd_cld_handler);
+               rspamd_fork_worker (rspamd_main, cf, 0, event_loop, rspamd_cld_handler,
+                               listen_sockets);
        }
        else if (cf->worker->flags & RSPAMD_WORKER_THREADED) {
-               rspamd_fork_worker (rspamd_main, cf, 0, event_loop, rspamd_cld_handler);
+               rspamd_fork_worker (rspamd_main, cf, 0, event_loop, rspamd_cld_handler,
+                               listen_sockets);
        }
        else {
                for (i = 0; i < cf->count; i++) {
                        rspamd_fork_worker (rspamd_main, cf, i, event_loop,
-                                       rspamd_cld_handler);
+                                       rspamd_cld_handler, listen_sockets);
                }
        }
 }