]> source.dussan.org Git - rspamd.git/commitdiff
* Introduce new system of worker's and modules initialization:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Mon, 16 Jan 2012 16:59:37 +0000 (20:59 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Mon, 16 Jan 2012 16:59:37 +0000 (20:59 +0400)
  - Removed legacy limitation of worker's types;
  - Using GQuarks to identify workers and modules;
  - Remove modules.sh script;
  - Add a common system of workers and modules;
  - Write management and configuration for new architecture.

26 files changed:
CMakeLists.txt
config.h.in
src/cfg_file.h
src/cfg_utils.c
src/cfg_xml.c
src/controller.c
src/fuzzy_storage.c
src/fuzzy_storage.h
src/kvstorage_server.c
src/kvstorage_server.h
src/lmtp.c
src/lmtp.h
src/logger.c
src/logger.h
src/main.c
src/main.h
src/plugins/chartable.c
src/plugins/fuzzy_check.c
src/plugins/regexp.c
src/plugins/spf.c
src/plugins/surbl.c
src/smtp.c
src/smtp.h
src/util.c
src/util.h
src/worker.c

index c02fbab9ed26ab28ebd446ed2981d76d58b37044..758081459a457286a559e19a471e2af7b3881595 100644 (file)
@@ -3,11 +3,14 @@
 #
 # Cmake configuration file
 #
+
+############################# INITIAL SECTION #############################################
+
 PROJECT(rspamd C)
 
 SET(RSPAMD_VERSION_MAJOR 0)
 SET(RSPAMD_VERSION_MINOR 4)
-SET(RSPAMD_VERSION_PATCH 6)
+SET(RSPAMD_VERSION_PATCH 7)
 
 
 SET(RSPAMD_VERSION         "${RSPAMD_VERSION_MAJOR}.${RSPAMD_VERSION_MINOR}.${RSPAMD_VERSION_PATCH}")
@@ -17,6 +20,8 @@ SET(RSPAMD_GROUP "nobody")
 
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0 FATAL_ERROR)
 
+############################# OPTIONS SECTION #############################################
+
 OPTION(DEBUG_MODE          "Enable debug output [default: ON]"                  ON)
 OPTION(ENABLE_OPTIMIZATION "Enable optimization [default: OFF]"                 OFF)
 OPTION(SKIP_RELINK_RPATH   "Skip relinking and full RPATH for the install tree" OFF)
@@ -30,7 +35,7 @@ OPTION(FORCE_GMIME24       "Link with gmime2.4 [default: OFF]"
 # Build optimized code for following CPU (default i386)
 #SET(CPU_TUNE               "i686")
 
-############################# CONFIG SECTION #############################################
+############################# INCLUDE SECTION #############################################
 
 INCLUDE(CheckIncludeFiles)
 INCLUDE(CheckFunctionExists)
@@ -41,6 +46,51 @@ INCLUDE(FindPkgConfig)
 INCLUDE(CheckCCompilerFlag)
 INCLUDE(FindPerl)
 
+############################# MODULES SECTION #############################################
+
+MACRO(_AddModulesForced MLIST WLIST)
+# Generate unique string for this build
+       STRING(RANDOM LENGTH 8 _MODULES_ID)
+       SET(MODULES_ID ${_MODULES_ID} CACHE INTERNAL "Modules ID" FORCE)
+       FILE(WRITE "src/modules.c" "/* ${MODULES_ID} */\n#include \"config.h\"\n")
+       FOREACH(MOD IN LISTS ${MLIST})
+               FILE(APPEND "src/modules.c" "extern module_t ${MOD}_module;\n")
+       ENDFOREACH(MOD IN LISTS ${MLIST})
+                
+       FILE(APPEND "src/modules.c" "\n\nmodule_t *modules[] = {\n")
+       
+       FOREACH(MOD IN LISTS ${MLIST})
+               FILE(APPEND "src/modules.c" "&${MOD}_module,\n")
+       ENDFOREACH(MOD IN LISTS ${MLIST})
+       FILE(APPEND "src/modules.c" "NULL\n};\n")
+       
+       FOREACH(WRK IN LISTS ${WLIST})
+               FILE(APPEND "src/modules.c" "extern worker_t ${WRK}_worker;\n")
+       ENDFOREACH(WRK IN LISTS ${WLIST})
+        
+       FILE(APPEND "src/modules.c" "\n\nworker_t *workers[] = {\n")
+       
+       FOREACH(WRK IN LISTS ${WLIST})
+               FILE(APPEND "src/modules.c" "&${WRK}_worker,\n")
+       ENDFOREACH(WRK IN LISTS ${WLIST})
+       FILE(APPEND "src/modules.c" "NULL\n};\n")
+ENDMACRO(_AddModulesForced MLIST WLIST)
+
+MACRO(AddModules MLIST WLIST)
+       _AddModulesForced(${MLIST} ${WLIST})
+       #IF(NOT EXISTS "src/modules.c")
+       #       _AddModulesForced(${MLIST} ${WLIST})
+       #ELSE(NOT EXISTS "src/modules.c")
+       #       FILE(STRINGS "src/modules.c" FILE_ID_RAW REGEX "^/.*[a-zA-Z0-9]+.*/$")
+       #       STRING(REGEX MATCH "[a-zA-Z0-9]+" FILE_ID "${FILE_ID_RAW}")
+       #       IF(NOT FILE_ID STREQUAL MODULES_ID)
+       #               MESSAGE("Regenerate modules info")
+       #               _AddModulesForced(${MLIST} ${WLIST})
+       #       ENDIF(NOT FILE_ID STREQUAL MODULES_ID)
+       #ENDIF(NOT EXISTS "src/modules.c")
+ENDMACRO(AddModules MLIST WLIST)
+
+############################# CONFIG SECTION #############################################
 # Initial set
 
 IF(CMAKE_INSTALL_PREFIX)
@@ -812,14 +862,14 @@ SET(PLUGINSSRC    src/plugins/surbl.c
                                src/plugins/chartable.c
                                src/plugins/fuzzy_check.c
                                src/plugins/spf.c)
+                               
+SET(MODULES_LIST surbl regexp chartable fuzzy_check spf)
+SET(WORKERS_LIST normal controller smtp lmtp fuzzy keystorage)
 
+AddModules(MODULES_LIST WORKERS_LIST)
 
 ################################ SUBDIRS SECTION ###########################
 
-ADD_CUSTOM_COMMAND(OUTPUT src/modules.c
-                                       COMMAND ${CMAKE_SOURCE_DIR}/utils/gen-modules.sh ${PLUGINSSRC}
-                                       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src)
-
 ADD_SUBDIRECTORY(contrib/lgpl)
 IF(GLIB_COMPAT)
        INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/contrib/lgpl")
index 8eedae5c03e1b9ef464cf27197d0da7b85644070..8ad00557dc40f1ba8cbd90202493958abd1c6ca9 100644 (file)
 /* Forwarded declaration */
 struct module_ctx;
 struct config_file;
+struct rspamd_worker;
 
 typedef struct module_s {
-       const char *name;
+       const gchar *name;
        int (*module_init_func)(struct config_file *cfg, struct module_ctx **ctx);
        int (*module_config_func)(struct config_file *cfg);
        int (*module_reconfig_func)(struct config_file *cfg);
 } module_t;
 
-extern module_t modules[];
+typedef struct worker_s {
+       const gchar *name;
+       gpointer (*worker_init_func)();
+       void (*worker_start_func)(struct rspamd_worker *worker);
+       gboolean has_socket;
+       gboolean unique;
+       gboolean threaded;
+       gboolean killable;
+} worker_t;
+
+extern module_t *modules[];
+extern worker_t *workers[];
 
 #endif
index 797f32837551b75c2d1e416fb3714b27cf07ff3f..b90171426741370c1290766a4bab03a4ab90b223 100644 (file)
@@ -224,7 +224,8 @@ struct config_scalar {
  * Config params for rspamd worker
  */
 struct worker_conf {
-       gint type;                                                                              /**< worker type                                                                                */
+       worker_t *worker;                                                               /**< pointer to worker type                                                             */
+       GQuark type;                                                                    /**< type of worker                                                                             */
        gchar *bind_host;                                                               /**< bind line                                                                                  */
        struct in_addr bind_addr;                                               /**< bind address in case of TCP socket                                 */
        guint16 bind_port;                                                              /**< bind port in case of TCP socket                                    */
@@ -299,7 +300,6 @@ struct config_file {
        GList *filters;                                                                 /**< linked list of all filters                                                 */
        GList *workers;                                                                 /**< linked list of all workers params                                  */
        gchar *filters_str;                                                             /**< string of filters                                                                  */
-       guint modules_num;
        GHashTable* modules_opts;                                               /**< hash for module options indexed by module name             */
        GHashTable* variables;                                                  /**< hash of $variables defined in config, indexed by variable name */
        GHashTable* metrics;                                                    /**< hash of metrics indexed by metric name                             */
index 2117025ba6cfe3efdf84892f653d45d0144579e9..f7d1b7ecf96c16bc55c480eb7b23582c51040e6b 100644 (file)
@@ -523,7 +523,7 @@ parse_filters_str (struct config_file *cfg, const gchar *str)
 {
        gchar                         **strvec, **p;
        struct filter                  *cur;
-       guint                           i;
+       module_t                                          **pmodule;
 
        if (str == NULL) {
                return;
@@ -538,18 +538,20 @@ parse_filters_str (struct config_file *cfg, const gchar *str)
        while (*p) {
                cur = NULL;
                /* Search modules from known C modules */
-               for (i = 0; i < cfg->modules_num; i++) {
+               pmodule = &modules[0];
+               while (*pmodule) {
                        g_strstrip (*p);
-                       if (modules[i].name != NULL && g_ascii_strcasecmp (modules[i].name, *p) == 0) {
+                       if ((*pmodule)->name != NULL && g_ascii_strcasecmp ((*pmodule)->name, *p) == 0) {
                                cur = memory_pool_alloc (cfg->cfg_pool, sizeof (struct filter));
                                cur->type = C_FILTER;
                                msg_debug ("found C filter %s", *p);
                                cur->func_name = memory_pool_strdup (cfg->cfg_pool, *p);
-                               cur->module = &modules[i];
+                               cur->module = (*pmodule);
                                cfg->filters = g_list_prepend (cfg->filters, cur);
 
                                break;
                        }
+                       pmodule ++;
                }
                if (cur != NULL) {
                        /* Go to next iteration */
index 87929f5107c4925e8a6bc2e00925bd5fcee5d0f3..8ecd7a986a317b53419cfc087942c57bf067c59a 100644 (file)
@@ -850,13 +850,9 @@ worker_foreach_callback (gpointer k, gpointer v, gpointer ud)
        struct xml_config_param        *cparam;
        GHashTable                     *worker_config;
 
-       if (cd->wrk->ctx == NULL) {
-               cd->wrk->ctx = init_workers_ctx (cd->wrk->type);
-       }
-
        if (!worker_options || (worker_config = g_hash_table_lookup (worker_options, &cd->wrk->type)) == NULL ||
                        (cparam = g_hash_table_lookup (worker_config, k)) == NULL) {
-               msg_warn ("unregistered worker attribute '%s' for worker %s", k, process_to_str (cd->wrk->type));
+               msg_warn ("unregistered worker attribute '%s' for worker %s", k, g_quark_to_string (cd->wrk->type));
        }
        else {
 
@@ -864,7 +860,7 @@ worker_foreach_callback (gpointer k, gpointer v, gpointer ud)
                        cparam->handler (cd->cfg, cd->ctx, NULL, v, NULL, cd->wrk->ctx, cparam->offset);
                }
                else {
-                       msg_err ("Bad error detected: module %s has not initialized its context", process_to_str (cd->wrk->type));
+                       msg_err ("Bad error detected: module %s has not initialized its context", g_quark_to_string (cd->wrk->type));
                }
        }
 }
@@ -894,31 +890,20 @@ gboolean
 worker_handle_type (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset)
 {
        struct worker_conf             *wrk = ctx->section_pointer;
-
+       GQuark                                                  type;
        
-       if (g_ascii_strcasecmp (data, "normal") == 0) {
-               wrk->type = TYPE_WORKER;
-               wrk->has_socket = TRUE;
-       }
-       else if (g_ascii_strcasecmp (data, "controller") == 0) {
-               wrk->type = TYPE_CONTROLLER;
-               wrk->has_socket = TRUE;
-       }
-       else if (g_ascii_strcasecmp (data, "lmtp") == 0) {
-               wrk->type = TYPE_LMTP;
-               wrk->has_socket = TRUE;
-       }
-       else if (g_ascii_strcasecmp (data, "smtp") == 0) {
-               wrk->type = TYPE_SMTP;
-               wrk->has_socket = TRUE;
-       }
-       else if (g_ascii_strcasecmp (data, "fuzzy") == 0) {
-               wrk->type = TYPE_FUZZY;
-               wrk->has_socket = FALSE;
-       }
-       else if (g_ascii_strcasecmp (data, "keystorage") == 0) {
-               wrk->type = TYPE_KVSTORAGE;
-               wrk->has_socket = TRUE;
+       type = g_quark_try_string (data);
+
+       if (type != 0) {
+                wrk->worker = get_worker_by_type (type);
+                if (wrk->worker == NULL) {
+                        msg_err ("unknown worker type: %s", data);
+                        return FALSE;
+                }
+                wrk->type = type;
+                if (wrk->worker->worker_init_func) {
+                        wrk->ctx = wrk->worker->worker_init_func ();
+                }
        }
        else {
                msg_err ("unknown worker type: %s", data);
@@ -2441,23 +2426,8 @@ xml_dump_workers (struct config_file *cfg, FILE *f)
                wrk = cur->data;
                
                rspamd_fprintf (f, "<worker>" EOL);
-               switch (wrk->type) {
-                       case TYPE_WORKER:
-                               rspamd_fprintf (f, "  <type>normal</type>" EOL);
-                               break;
-                       case TYPE_CONTROLLER:
-                               rspamd_fprintf (f, "  <type>controller</type>" EOL);
-                               break;
-                       case TYPE_FUZZY:
-                               rspamd_fprintf (f, "  <type>fuzzy</type>" EOL);
-                               break;
-                       case TYPE_LMTP:
-                               rspamd_fprintf (f, "  <type>lmtp</type>" EOL);
-                               break;
-                       case TYPE_SMTP:
-                               rspamd_fprintf (f, "  <type>smtp</type>" EOL);
-                               break;
-               }
+
+               rspamd_fprintf (f, "  <type>%s</type>" EOL, g_quark_to_string (wrk->type));
                escaped_str = g_markup_escape_text (wrk->bind_host, -1); 
                rspamd_fprintf (f, "  <bind_socket>%s</bind_socket>" EOL, escaped_str);
                g_free (escaped_str);
index 1b78b82f5558afd69b07228b3224b24a8ede37fd..b9ec3677c5fab94a08cbfa1bb75abdfac6d8ca58 100644 (file)
@@ -30,7 +30,6 @@
 #include "upstream.h"
 #include "cfg_file.h"
 #include "cfg_xml.h"
-#include "modules.h"
 #include "map.h"
 #include "dns.h"
 #include "tokenizers/tokenizers.h"
 /* 120 seconds for controller's IO */
 #define CONTROLLER_IO_TIMEOUT 120
 
+/* Init functions */
+gpointer init_controller ();
+void start_controller (struct rspamd_worker *worker);
+
+worker_t controller_worker = {
+       "controller",                           /* Name */
+       init_controller,                        /* Init function */
+       start_controller,                       /* Start function */
+       TRUE,                                           /* Has socket */
+       FALSE,                                          /* Non unique */
+       FALSE,                                          /* Non threaded */
+       TRUE                                            /* Killable */
+};
+
 enum command_type {
        COMMAND_PASSWORD,
        COMMAND_QUIT,
@@ -1229,16 +1242,18 @@ accept_socket (gint fd, short what, void *arg)
 }
 
 gpointer
-init_controller (void)
+init_controller ()
 {
        struct rspamd_controller_ctx       *ctx;
+       GQuark                                                          type;
 
+       type = g_quark_try_string ("controller");
        ctx = g_malloc0 (sizeof (struct rspamd_controller_ctx));
 
        ctx->timeout = CONTROLLER_IO_TIMEOUT * 1000;
 
-       register_worker_opt (TYPE_CONTROLLER, "password", xml_handle_string, ctx, G_STRUCT_OFFSET (struct rspamd_controller_ctx, password));
-       register_worker_opt (TYPE_CONTROLLER, "timeout", xml_handle_seconds, ctx, G_STRUCT_OFFSET (struct rspamd_controller_ctx, timeout));
+       register_worker_opt (type, "password", xml_handle_string, ctx, G_STRUCT_OFFSET (struct rspamd_controller_ctx, password));
+       register_worker_opt (type, "timeout", xml_handle_seconds, ctx, G_STRUCT_OFFSET (struct rspamd_controller_ctx, timeout));
 
        return ctx;
 }
index 408d39960c21f096f5841a3bc0cb4d0b4bfefb74..d8344b96ce28354943c3c652cce1837993176c55 100644 (file)
@@ -34,7 +34,6 @@
 #include "cfg_file.h"
 #include "cfg_xml.h"
 #include "url.h"
-#include "modules.h"
 #include "message.h"
 #include "fuzzy.h"
 #include "bloom.h"
 /* Current version of fuzzy hash file format */
 #define CURRENT_FUZZY_VERSION 1
 
+/* Init functions */
+gpointer init_fuzzy ();
+void start_fuzzy (struct rspamd_worker *worker);
+
+worker_t fuzzy_worker = {
+       "fuzzy",                                        /* Name */
+       init_fuzzy,                                     /* Init function */
+       start_fuzzy,                            /* Start function */
+       TRUE,                                           /* Has socket */
+       TRUE,                                           /* Non unique */
+       FALSE,                                          /* Non threaded */
+       FALSE                                           /* Non killable */
+};
+
 static GQueue                  *hashes[BUCKETS];
 static GQueue                  *frequent;
 #ifdef WITH_JUDY
@@ -756,9 +769,12 @@ sync_callback (gint fd, short what, void *arg)
 }
 
 gpointer
-init_fuzzy_storage (void)
+init_fuzzy (void)
 {
        struct rspamd_fuzzy_storage_ctx       *ctx;
+       GQuark                                                         type;
+
+       type = g_quark_try_string ("fuzzy");
 
        ctx = g_malloc0 (sizeof (struct rspamd_fuzzy_storage_ctx));
 
@@ -766,15 +782,15 @@ init_fuzzy_storage (void)
        ctx->frequent_score = DEFAULT_FREQUENT_SCORE;
        ctx->expire = DEFAULT_EXPIRE;
 
-       register_worker_opt (TYPE_FUZZY, "hashfile", xml_handle_string, ctx,
+       register_worker_opt (type, "hashfile", xml_handle_string, ctx,
                        G_STRUCT_OFFSET (struct rspamd_fuzzy_storage_ctx, hashfile));
-       register_worker_opt (TYPE_FUZZY, "max_mods", xml_handle_uint32, ctx,
+       register_worker_opt (type, "max_mods", xml_handle_uint32, ctx,
                        G_STRUCT_OFFSET (struct rspamd_fuzzy_storage_ctx, max_mods));
-       register_worker_opt (TYPE_FUZZY, "frequent_score", xml_handle_uint32, ctx,
+       register_worker_opt (type, "frequent_score", xml_handle_uint32, ctx,
                                G_STRUCT_OFFSET (struct rspamd_fuzzy_storage_ctx, frequent_score));
-       register_worker_opt (TYPE_FUZZY, "expire", xml_handle_seconds, ctx,
+       register_worker_opt (type, "expire", xml_handle_seconds, ctx,
                                        G_STRUCT_OFFSET (struct rspamd_fuzzy_storage_ctx, expire));
-       register_worker_opt (TYPE_FUZZY, "use_judy", xml_handle_boolean, ctx,
+       register_worker_opt (type, "use_judy", xml_handle_boolean, ctx,
                                G_STRUCT_OFFSET (struct rspamd_fuzzy_storage_ctx, use_judy));
 
        return ctx;
@@ -784,14 +800,13 @@ init_fuzzy_storage (void)
  * Start worker process
  */
 void
-start_fuzzy_storage (struct rspamd_worker *worker)
+start_fuzzy (struct rspamd_worker *worker)
 {
        struct sigaction                signals;
        struct event                    sev;
        gint                            retries = 0;
 
        worker->srv->pid = getpid ();
-       worker->srv->type = TYPE_FUZZY;
 
        event_init ();
 
index f5196b1d60f6fb2d6e52e2e0ffc7bd83e0516f63..2e60670dfa664d11cc37b454c8a2977452e1d129 100644 (file)
@@ -27,7 +27,4 @@ struct fuzzy_session {
        struct sockaddr_storage sa;
 };
 
-gpointer init_fuzzy_storage (void);
-void start_fuzzy_storage (struct rspamd_worker *worker);
-
 #endif
index c55c7c37e30c3238fa41e7069f79967f52038c71..059a0e6e87d58c8eb7e3c6cb6cdc967f540e2a55 100644 (file)
@@ -63,6 +63,20 @@ static sig_atomic_t soft_wanna_die = 0;
        g_static_mutex_unlock (thr->log_mtx);                                                                                                                           \
 } while (0)
 
+/* Init functions */
+gpointer init_keystorage ();
+void start_keystorage (struct rspamd_worker *worker);
+
+worker_t keystorage_worker = {
+       "keystorage",                           /* Name */
+       init_keystorage,                        /* Init function */
+       start_keystorage,                       /* Start function */
+       TRUE,                                           /* Has socket */
+       FALSE,                                          /* Non unique */
+       TRUE,                                           /* Non threaded */
+       FALSE                                           /* Non killable */
+};
+
 #ifndef HAVE_SA_SIGINFO
 static void
 sig_handler (gint signo)
@@ -86,19 +100,21 @@ sig_handler (gint signo, siginfo_t *info, void *unused)
 }
 
 gpointer
-init_kvstorage_worker (void)
+init_keystorage (void)
 {
        struct kvstorage_worker_ctx         *ctx;
+       GQuark                                                          type;
 
+       type = g_quark_try_string ("keystorage");
        ctx = g_malloc0 (sizeof (struct kvstorage_worker_ctx));
        ctx->pool = memory_pool_new (memory_pool_get_size ());
 
        /* Set default values */
        ctx->timeout_raw = 300000;
 
-       register_worker_opt (TYPE_KVSTORAGE, "timeout", xml_handle_seconds, ctx,
+       register_worker_opt (type, "timeout", xml_handle_seconds, ctx,
                                        G_STRUCT_OFFSET (struct kvstorage_worker_ctx, timeout_raw));
-       register_worker_opt (TYPE_KVSTORAGE, "redis", xml_handle_boolean, ctx,
+       register_worker_opt (type, "redis", xml_handle_boolean, ctx,
                                                G_STRUCT_OFFSET (struct kvstorage_worker_ctx, is_redis));
        return ctx;
 }
@@ -1066,7 +1082,7 @@ create_kvstorage_thread (struct rspamd_worker *worker, struct kvstorage_worker_c
  * Start worker process
  */
 void
-start_kvstorage_worker (struct rspamd_worker *worker)
+start_keystorage (struct rspamd_worker *worker)
 {
        struct sigaction                         signals;
        struct kvstorage_worker_ctx         *ctx = worker->ctx;
index e2d670bade98177d8f836c960d21a2bf874e1f91..aeb11e2496d60eeccddf964c4fd06f0c69483387 100644 (file)
@@ -93,7 +93,4 @@ struct kvstorage_session {
        time_t now;
 };
 
-gpointer init_kvstorage_worker (void);
-void start_kvstorage_worker (struct rspamd_worker *worker);
-
 #endif /* KVSTORAGE_SERVER_H_ */
index 81b546d4f069b02303376480591fcf29a705d917..da38dc6aeb9db2fbae2a3513c4410a6fa55d745c 100644 (file)
@@ -30,7 +30,6 @@
 #include "cfg_file.h"
 #include "util.h"
 #include "url.h"
-#include "modules.h"
 #include "message.h"
 
 static gchar                     greetingbuf[1024];
@@ -38,6 +37,18 @@ static struct timeval           io_tv;
 
 static gboolean                 lmtp_write_socket (void *arg);
 
+void start_lmtp (struct rspamd_worker *worker);
+
+worker_t lmtp_worker = {
+       "controller",                           /* Name */
+       NULL,                                           /* Init function */
+       start_lmtp,                                     /* Start function */
+       TRUE,                                           /* Has socket */
+       FALSE,                                          /* Non unique */
+       FALSE,                                          /* Non threaded */
+       TRUE                                            /* Killable */
+};
+
 #ifndef HAVE_SA_SIGINFO
 static void
 sig_handler (gint signo)
@@ -279,15 +290,14 @@ accept_socket (gint fd, short what, void *arg)
  * Start lmtp worker process
  */
 void
-start_lmtp_worker (struct rspamd_worker *worker)
+start_lmtp (struct rspamd_worker *worker)
 {
        struct sigaction                signals;
-       gint                            i;
        gchar                          *hostbuf;
        gsize                           hostmax;
+       module_t                                          **mod;
 
        worker->srv->pid = getpid ();
-       worker->srv->type = TYPE_LMTP;
        worker->ctx = event_init ();
        g_mime_init (0);
 
@@ -310,8 +320,10 @@ start_lmtp_worker (struct rspamd_worker *worker)
        event_add (&worker->bind_ev, NULL);
 
        /* Perform modules configuring */
-       for (i = 0; i < MODULES_NUM; i++) {
-               modules[i].module_config_func (worker->srv->cfg);
+       mod = &modules[0];
+       while (*mod) {
+               (*mod)->module_config_func (worker->srv->cfg);
+               mod ++;
        }
 
        /* Fill hostname buf */
index d7c13c497296104311ae67c24bb0332877c1578f..863c6eacd32134c55d85c73f226fdf1046e72602 100644 (file)
@@ -15,6 +15,4 @@
 #define LMTP_NO_RCPT        554
 #define LMTP_TEMP_FAIL      421
 
-void start_lmtp_worker (struct rspamd_worker *worker);
-
 #endif
index 219f04cac2b3a0a7240a1c98dfdf3fa69fe9f850..2abdf0dfc5e2f40e84ae45196296cf399b0b95a3 100644 (file)
@@ -54,7 +54,7 @@ struct rspamd_logger_s {
        sig_atomic_t             do_reopen_log;
        enum rspamd_log_type     type;
        pid_t                    pid;
-       enum process_type                process_type;
+       GQuark                                   process_type;
        radix_tree_t            *debug_ip;
        guint32                  last_line_cksum;
        guint32                  repeats;
@@ -252,7 +252,7 @@ reopen_log (rspamd_logger_t *logger)
  * Setup logger
  */
 void
-rspamd_set_logger (enum rspamd_log_type type, enum process_type ptype, struct rspamd_main *rspamd)
+rspamd_set_logger (enum rspamd_log_type type, GQuark ptype, struct rspamd_main *rspamd)
 {
        gchar                           **strvec, *p, *err;
        gint                            num, i, k;
@@ -340,7 +340,7 @@ rspamd_set_logger (enum rspamd_log_type type, enum process_type ptype, struct rs
  * Used after fork() for updating structure params
  */
 void
-update_log_pid (enum process_type ptype, rspamd_logger_t *rspamd_log)
+update_log_pid (GQuark ptype, rspamd_logger_t *rspamd_log)
 {
        rspamd_log->pid = getpid ();
        rspamd_log->process_type = ptype;
@@ -568,7 +568,7 @@ file_log_function (const gchar * log_domain, const gchar *function, GLogLevelFla
                        tms = localtime (&now);
 
                        strftime (timebuf, sizeof (timebuf), "%F %H:%M:%S", tms);
-                       cptype = process_to_str (rspamd_log->process_type);
+                       cptype = g_quark_to_string (rspamd_log->process_type);
 
                        if (rspamd_log->cfg->log_color) {
                                if (log_level >= G_LOG_LEVEL_INFO) {
index e25d6bfff2a1d3b9d39f192d6c213495f3661933..6d0cac4b81c5b74183956b58012521c17006391e 100644 (file)
@@ -15,7 +15,7 @@ typedef struct rspamd_logger_s rspamd_logger_t;
 /**
  * Init logger
  */
-void rspamd_set_logger (enum rspamd_log_type type, enum process_type ptype, struct rspamd_main *main);
+void rspamd_set_logger (enum rspamd_log_type type, GQuark ptype, struct rspamd_main *main);
 /**
  * Open log file or initialize other structures
  */
@@ -45,7 +45,7 @@ gint reopen_log_priv (rspamd_logger_t *logger, uid_t uid, gid_t gid);
 /**
  * Set log pid
  */
-void update_log_pid (enum process_type ptype, rspamd_logger_t *logger);
+void update_log_pid (GQuark ptype, rspamd_logger_t *logger);
 
 /**
  * Flush log buffer for some types of logging
index e16d9d5e0352239118d8932513e3f6ab2ed34f63..bb62099749c1a4c3f9f109f06c2b338163fd41e2 100644 (file)
@@ -262,9 +262,9 @@ drop_priv (struct rspamd_main *rspamd)
 }
 
 static void
-config_logger (struct rspamd_main *rspamd, gboolean is_fatal)
+config_logger (struct rspamd_main *rspamd, GQuark type, gboolean is_fatal)
 {
-       rspamd_set_logger (rspamd->cfg->log_type, TYPE_MAIN, rspamd);
+       rspamd_set_logger (rspamd->cfg->log_type, type, rspamd);
        if (open_log_priv (rspamd->logger, rspamd->workers_uid, rspamd->workers_gid) == -1) {
                if (is_fatal) {
                        fprintf (stderr, "Fatal error, cannot open logfile, exiting\n");
@@ -283,12 +283,12 @@ reread_config (struct rspamd_main *rspamd)
        gchar                           *cfg_file;
        GList                          *l;
        struct filter                  *filt;
+       GQuark                                                  type;
 
        tmp_cfg = (struct config_file *)g_malloc (sizeof (struct config_file));
        if (tmp_cfg) {
                bzero (tmp_cfg, sizeof (struct config_file));
                tmp_cfg->cfg_pool = memory_pool_new (memory_pool_get_size ());
-               tmp_cfg->modules_num = MODULES_NUM;
                init_defaults (tmp_cfg);
                cfg_file = memory_pool_strdup (tmp_cfg->cfg_pool, rspamd->cfg->cfg_name);
                /* Save some variables */
@@ -309,7 +309,8 @@ reread_config (struct rspamd_main *rspamd)
                        if (is_debug) {
                                rspamd->cfg->log_level = G_LOG_LEVEL_DEBUG;
                        }
-                       config_logger (rspamd, FALSE);
+                       type = g_quark_try_string ("main");
+                       config_logger (rspamd, type, FALSE);
                        /* Pre-init of cache */
                        rspamd->cfg->cache = g_new0 (struct symbols_cache, 1);
                        rspamd->cfg->cache->static_pool = memory_pool_new (memory_pool_get_size ());
@@ -368,15 +369,9 @@ fork_worker (struct rspamd_main *rspamd, struct worker_conf *cf)
                cur->type = cf->type;
                cur->pid = fork ();
                cur->cf = g_malloc (sizeof (struct worker_conf));
-               /* Copy or init context */
-               if (cf->ctx) {
-                       cur->ctx = cf->ctx;
-               }
-               else {
-                       cur->ctx = init_workers_ctx (cf->type);
-               }
                memcpy (cur->cf, cf, sizeof (struct worker_conf));
                cur->pending = FALSE;
+               cur->ctx = cf->ctx;
                switch (cur->pid) {
                case 0:
                        /* Update pid for logging */
@@ -385,45 +380,10 @@ fork_worker (struct rspamd_main *rspamd, struct worker_conf *cf)
                        drop_priv (rspamd);
                        /* Set limits */
                        set_worker_limits (cf);
-                       switch (cf->type) {
-                       case TYPE_CONTROLLER:
-                               setproctitle ("controller process");
-                               rspamd_pidfile_close (rspamd->pfh);
-                               msg_info ("starting controller process %P", getpid ());
-                               start_controller (cur);
-                               break;
-                       case TYPE_LMTP:
-                               setproctitle ("lmtp process");
-                               rspamd_pidfile_close (rspamd->pfh);
-                               msg_info ("starting lmtp process %P", getpid ());
-                               start_lmtp_worker (cur);
-                               break;
-                       case TYPE_SMTP:
-                               setproctitle ("smtp process");
-                               rspamd_pidfile_close (rspamd->pfh);
-                               msg_info ("starting smtp process %P", getpid ());
-                               start_smtp_worker (cur);
-                               break;
-                       case TYPE_FUZZY:
-                               setproctitle ("fuzzy storage");
-                               rspamd_pidfile_close (rspamd->pfh);
-                               msg_info ("starting fuzzy storage process %P", getpid ());
-                               start_fuzzy_storage (cur);
-                               break;
-                       case TYPE_KVSTORAGE:
-                               setproctitle ("kv storage");
-                               rspamd_pidfile_close (rspamd->pfh);
-                               msg_info ("starting key-value storage process %P", getpid ());
-                               start_kvstorage_worker (cur);
-                               break;
-                       case TYPE_WORKER:
-                       default:
-                               setproctitle ("worker process");
-                               rspamd_pidfile_close (rspamd->pfh);
-                               msg_info ("starting worker process %P", getpid ());
-                               start_worker (cur);
-                               break;
-                       }
+                       setproctitle ("%s process", cf->worker->name);
+                       rspamd_pidfile_close (rspamd->pfh);
+                       msg_info ("starting %s process %P", cf->worker->name, getpid ());
+                       cf->worker->worker_start_func (cur);
                        break;
                case -1:
                        msg_err ("cannot fork main process. %s", strerror (errno));
@@ -584,7 +544,7 @@ spawn_workers (struct rspamd_main *rspamd)
        while (cur) {
                cf = cur->data;
 
-               if (cf->has_socket) {
+               if (cf->worker->has_socket) {
                        if ((p = g_hash_table_lookup (listen_sockets, GINT_TO_POINTER (
                                                                make_listen_key (&cf->bind_addr, cf->bind_port, cf->bind_family, cf->bind_host)))) == NULL) {
                                /* Create listen socket */
@@ -603,13 +563,13 @@ spawn_workers (struct rspamd_main *rspamd)
                        cf->listen_sock = listen_sock;
                }
                
-               if (cf->type == TYPE_FUZZY) {
+               if (cf->worker->unique) {
                        if (cf->count > 1) {
-                               msg_err ("cannot spawn more than 1 fuzzy storage worker, so spawn one");
+                               msg_err ("cannot spawn more than 1 %s worker, so spawn one", cf->worker->name);
                        }
                        fork_worker (rspamd, cf);
                }
-               else if (cf->type == TYPE_KVSTORAGE) {
+               else if (cf->worker->threaded) {
                        fork_worker (rspamd, cf);
                }
                else {
@@ -646,19 +606,19 @@ wait_for_workers (gpointer key, gpointer value, gpointer unused)
        if (waitpid (w->pid, &res, 0) == -1) {
                if (errno == EINTR) {
                        got_alarm = 1;
-                       if (w->type != TYPE_KVSTORAGE) {
+                       if (w->cf->worker->killable) {
                                msg_info ("terminate worker %P with SIGKILL", w->pid);
                                kill (w->pid, SIGKILL);
                        }
                        else {
-                               msg_info ("waiting for storages to sync");
+                               msg_info ("waiting for workers to sync");
                                wait_for_workers (key, value, unused);
                                return TRUE;
                        }
                }
        }
 
-       msg_info ("%s process %P terminated %s", process_to_str (w->type), w->pid,
+       msg_info ("%s process %P terminated %s", g_quark_to_string (w->type), w->pid,
                        got_alarm ? "hardly" : "softly");
        g_free (w->cf);
        g_free (w);
@@ -841,24 +801,6 @@ print_symbols_cache (struct config_file *cfg)
        }
 }
 
-gpointer
-init_workers_ctx (enum process_type type)
-{
-       switch (type) {
-       case TYPE_WORKER:
-               return init_worker ();
-       case TYPE_CONTROLLER:
-               return init_controller ();
-       case TYPE_FUZZY:
-               return init_fuzzy_storage ();
-       case TYPE_SMTP:
-               return init_smtp_worker ();
-       case TYPE_KVSTORAGE:
-               return init_kvstorage_worker ();
-       default:
-               return NULL;
-       }
-}
 
 gint
 main (gint argc, gchar **argv, gchar **env)
@@ -870,6 +812,8 @@ main (gint argc, gchar **argv, gchar **env)
        struct filter                  *filt;
        pid_t                           wrk;
        GList                          *l;
+       worker_t                      **pworker;
+       GQuark                                                  type;
 
 #ifdef HAVE_SA_SIGINFO
        signals_info = g_queue_new ();
@@ -893,7 +837,6 @@ main (gint argc, gchar **argv, gchar **env)
 
        memset (rspamd_main->cfg, 0, sizeof (struct config_file));
        rspamd_main->cfg->cfg_pool = memory_pool_new (memory_pool_get_size ());
-       rspamd_main->cfg->modules_num = MODULES_NUM;
        init_defaults (rspamd_main->cfg);
 
        memset (&signals, 0, sizeof (struct sigaction));
@@ -910,6 +853,8 @@ main (gint argc, gchar **argv, gchar **env)
                rspamd_main->cfg->log_level = G_LOG_LEVEL_CRITICAL;
        }
 
+       type = g_quark_from_static_string ("main");
+
 #ifdef HAVE_SETLOCALE
        /* Set locale setting to C locale to avoid problems in future */
        setlocale (LC_ALL, "C");
@@ -919,13 +864,20 @@ main (gint argc, gchar **argv, gchar **env)
 #endif
 
        /* First set logger to console logger */
-       rspamd_set_logger (RSPAMD_LOG_CONSOLE, TYPE_MAIN, rspamd_main);
+       rspamd_set_logger (RSPAMD_LOG_CONSOLE, type, rspamd_main);
        (void)open_log (rspamd_main->logger);
        g_log_set_default_handler (rspamd_glib_log_function, rspamd_main->logger);
 
        detect_priv (rspamd_main);
        init_lua (rspamd_main->cfg);
 
+       pworker = &workers[0];
+       while (*pworker) {
+               /* Init string quarks */
+               (void)g_quark_from_static_string ((*pworker)->name);
+               pworker ++;
+       }
+
        /* Init counters */
        counters = rspamd_hash_new_shared (rspamd_main->server_pool, g_str_hash, g_str_equal, 64);
        /* Init listen sockets hash */
@@ -998,7 +950,7 @@ main (gint argc, gchar **argv, gchar **env)
        rlim.rlim_cur = 100 * 1024 * 1024;
        setrlimit (RLIMIT_STACK, &rlim);
 
-       config_logger (rspamd_main, TRUE);
+       config_logger (rspamd_main, type, TRUE);
 
        msg_info ("rspamd " RVERSION " is starting, build id: " RID);
        rspamd_main->cfg->cfg_name = memory_pool_strdup (rspamd_main->cfg->cfg_pool, rspamd_main->cfg->cfg_name);
@@ -1011,7 +963,7 @@ main (gint argc, gchar **argv, gchar **env)
 
        /* Write info */
        rspamd_main->pid = getpid ();
-       rspamd_main->type = TYPE_MAIN;
+       rspamd_main->type = type;
 
        init_signals (&signals, sig_handler);
 
@@ -1098,14 +1050,14 @@ main (gint argc, gchar **argv, gchar **env)
 
                                if (WIFEXITED (res) && WEXITSTATUS (res) == 0) {
                                        /* Normal worker termination, do not fork one more */
-                                       msg_info ("%s process %P terminated normally", process_to_str (cur->type), cur->pid);
+                                       msg_info ("%s process %P terminated normally", g_quark_to_string (cur->type), cur->pid);
                                }
                                else {
                                        if (WIFSIGNALED (res)) {
-                                               msg_warn ("%s process %P terminated abnormally by signal: %d", process_to_str (cur->type), cur->pid, WTERMSIG (res));
+                                               msg_warn ("%s process %P terminated abnormally by signal: %d", g_quark_to_string (cur->type), cur->pid, WTERMSIG (res));
                                        }
                                        else {
-                                               msg_warn ("%s process %P terminated abnormally", process_to_str (cur->type), cur->pid);
+                                               msg_warn ("%s process %P terminated abnormally", g_quark_to_string (cur->type), cur->pid);
                                        }
                                        /* Fork another worker in replace of dead one */
                                        delay_fork (cur->cf);
index ada9d97e481929acdbe2117ecac580f9339aadd7..63a94b462294a73ee443166c1542373ea7fd4db0 100644 (file)
@@ -49,7 +49,7 @@ struct rspamd_worker {
        gboolean is_dying;                                                                                      /**< if worker is going to shutdown                                     */
        gboolean pending;                                                                                       /**< if worker is pending to run                                        */
        struct rspamd_main *srv;                                                                        /**< pointer to server structure                                        */
-       enum process_type type;                                                                         /**< process type                                                                       */
+       GQuark type;                                                                                            /**< process type                                                                       */
        struct event sig_ev_usr1;                                                                       /**< signals event                                                                      */
        struct event sig_ev_usr2;                                                                       /**< signals event                                                                      */
        struct event bind_ev;                                                                           /**< socket events                                                                      */
@@ -57,6 +57,10 @@ struct rspamd_worker {
        gpointer ctx;                                                                                           /**< worker's specific data                                                     */
 };
 
+/**
+ * Module
+ */
+
 struct pidfh;
 struct config_file;
 struct tokenizer;
@@ -88,8 +92,8 @@ struct rspamd_main {
        struct config_file *cfg;                                                                        /**< pointer to config structure                                        */
        pid_t pid;                                                                                                      /**< main pid                                                                           */
        /* Pid file structure */
-       rspamd_pidfh_t *pfh;                                                                                    /**< struct pidfh for pidfile                                           */
-       enum process_type type;                                                                         /**< process type                                                                       */
+       rspamd_pidfh_t *pfh;                                                                            /**< struct pidfh for pidfile                                           */
+       GQuark type;                                                                                            /**< process type                                                                       */
        guint ev_initialized;                                                                           /**< is event system is initialized                                     */
        struct rspamd_stat *stat;                                                                       /**< pointer to statistics                                                      */
 
@@ -262,22 +266,11 @@ struct c_module {
        struct module_ctx *ctx;                                                                         /**< pointer to context                                                         */
 };
 
-/* Workers' initialization and start functions */
-gpointer init_worker (void);
-void start_worker (struct rspamd_worker *worker);
-gpointer init_controller (void);
-void start_controller (struct rspamd_worker *worker);
-
 /**
  * Register custom controller function
  */
 void register_custom_controller_command (const gchar *name, controller_func_t handler, gboolean privilleged, gboolean require_message);
 
-/**
- * Initialize context for worker of specified type
- */
-gpointer init_workers_ctx (enum process_type type);
-
 /**
  * If set, reopen log file on next write
  */
index 6458b3e2d0a0bc63aa5c6b53030f74bcffd26fad..87b419076c5edfc5e4bf3201066ae89626e3a595 100644 (file)
 #define DEFAULT_SYMBOL "R_CHARSET_MIXED"
 #define DEFAULT_THRESHOLD 0.1
 
+/* Initialization */
+gint chartable_module_init (struct config_file *cfg, struct module_ctx **ctx);
+gint chartable_module_config (struct config_file *cfg);
+gint chartable_module_reconfig (struct config_file *cfg);
+
+module_t chartable_module = {
+       "chartable",
+       chartable_module_init,
+       chartable_module_config,
+       chartable_module_reconfig
+};
+
 struct chartable_ctx {
        gint                            (*filter) (struct worker_task * task);
        gchar                           *symbol;
index f7191117bec5bf516a1a8892c0e6689e47dcfc4b..ef88cab6b3046f9416f198394ec6b1cd86553136 100644 (file)
@@ -126,6 +126,18 @@ static void                     fuzzy_symbol_callback (struct worker_task *task,
 static void                     fuzzy_add_handler (gchar **args, struct controller_session *session);
 static void                     fuzzy_delete_handler (gchar **args, struct controller_session *session);
 
+/* Initialization */
+gint fuzzy_check_module_init (struct config_file *cfg, struct module_ctx **ctx);
+gint fuzzy_check_module_config (struct config_file *cfg);
+gint fuzzy_check_module_reconfig (struct config_file *cfg);
+
+module_t fuzzy_check_module = {
+       "fuzzy_check",
+       fuzzy_check_module_init,
+       fuzzy_check_module_config,
+       fuzzy_check_module_reconfig
+};
+
 /* Flags string is in format <numeric_flag>:<SYMBOL>:weight[, <numeric_flag>:<SYMBOL>:weight...] */
 static void
 parse_flags_string (struct config_file *cfg, gchar *str)
index 77c67015c37417016cf2796cc105435b6d5fb389..ea1841969160f11a49685c565d6b116b51e3beea 100644 (file)
@@ -91,6 +91,18 @@ static gboolean                 rspamd_check_smtp_data (struct worker_task *task
 static gboolean                 rspamd_regexp_occurs_number (struct worker_task *task, GList * args, void *unused);
 static void                     process_regexp_item (struct worker_task *task, void *user_data);
 
+/* Initialization */
+gint regexp_module_init (struct config_file *cfg, struct module_ctx **ctx);
+gint regexp_module_config (struct config_file *cfg);
+gint regexp_module_reconfig (struct config_file *cfg);
+
+module_t regexp_module = {
+       "regexp",
+       regexp_module_init,
+       regexp_module_config,
+       regexp_module_reconfig
+};
+
 static gint
 luaopen_regexp (lua_State * L)
 {
index 12ec80e6794a7483ff57ce327cdb582188601ad8..093c57703c84f96c4b9ebacbd549e34cda7ded4c 100644 (file)
@@ -67,6 +67,18 @@ static void                   spf_symbol_callback (struct worker_task *task, voi
 static GList *                spf_record_copy (GList *addrs);
 static void                   spf_record_destroy (gpointer list);
 
+/* Initialization */
+gint spf_module_init (struct config_file *cfg, struct module_ctx **ctx);
+gint spf_module_config (struct config_file *cfg);
+gint spf_module_reconfig (struct config_file *cfg);
+
+module_t spf_module = {
+       "spf",
+       spf_module_init,
+       spf_module_config,
+       spf_module_reconfig
+};
+
 gint
 spf_module_init (struct config_file *cfg, struct module_ctx **ctx)
 {
index fe0c1d6de3e1a9b2b649cbb107f7b6c9aa49c311..2482dc58956e3fefe31703f84809c51a3fe2ce14 100644 (file)
@@ -75,6 +75,18 @@ surbl_error_quark (void)
        return g_quark_from_static_string ("surbl-error-quark");
 }
 
+/* Initialization */
+gint surbl_module_init (struct config_file *cfg, struct module_ctx **ctx);
+gint surbl_module_config (struct config_file *cfg);
+gint surbl_module_reconfig (struct config_file *cfg);
+
+module_t surbl_module = {
+       "surbl",
+       surbl_module_init,
+       surbl_module_config,
+       surbl_module_reconfig
+};
+
 static void
 exception_insert (gpointer st, gconstpointer key, gpointer value)
 {
index cc0e933917d4cb08538c72c2e9ff4467721b190c..2b5236cc6e18e37e6b674d92a3284cb670afc668 100644 (file)
@@ -52,6 +52,19 @@ static gboolean smtp_write_socket (void *arg);
 
 static sig_atomic_t                    wanna_die = 0;
 
+/* Init functions */
+gpointer init_smtp ();
+void start_smtp (struct rspamd_worker *worker);
+
+worker_t smtp_worker = {
+       "smtp",                                         /* Name */
+       init_smtp,                                      /* Init function */
+       start_smtp,                                     /* Start function */
+       TRUE,                                           /* Has socket */
+       FALSE,                                          /* Non unique */
+       FALSE,                                          /* Non threaded */
+       TRUE                                            /* Killable */
+};
 
 #ifndef HAVE_SA_SIGINFO
 static void
@@ -907,9 +920,12 @@ make_capabilities (struct smtp_worker_ctx *ctx, const gchar *line)
 }
 
 gpointer
-init_smtp_worker (void)
+init_smtp (void)
 {
-       struct smtp_worker_ctx         *ctx;
+       struct smtp_worker_ctx                  *ctx;
+       GQuark                                                          type;
+
+       type = g_quark_try_string ("smtp");
 
        ctx = g_malloc0 (sizeof (struct smtp_worker_ctx));
        ctx->pool = memory_pool_new (memory_pool_get_size ());
@@ -922,25 +938,25 @@ init_smtp_worker (void)
        ctx->max_errors = DEFAULT_MAX_ERRORS;
        ctx->reject_message = DEFAULT_REJECT_MESSAGE;
 
-       register_worker_opt (TYPE_SMTP, "upstreams", xml_handle_string, ctx,
+       register_worker_opt (type, "upstreams", xml_handle_string, ctx,
                                G_STRUCT_OFFSET (struct smtp_worker_ctx, upstreams_str));
-       register_worker_opt (TYPE_SMTP, "banner", xml_handle_string, ctx,
+       register_worker_opt (type, "banner", xml_handle_string, ctx,
                                        G_STRUCT_OFFSET (struct smtp_worker_ctx, smtp_banner_str));
-       register_worker_opt (TYPE_SMTP, "timeout", xml_handle_seconds, ctx,
+       register_worker_opt (type, "timeout", xml_handle_seconds, ctx,
                                        G_STRUCT_OFFSET (struct smtp_worker_ctx, smtp_timeout_raw));
-       register_worker_opt (TYPE_SMTP, "delay", xml_handle_seconds, ctx,
+       register_worker_opt (type, "delay", xml_handle_seconds, ctx,
                                        G_STRUCT_OFFSET (struct smtp_worker_ctx, smtp_delay));
-       register_worker_opt (TYPE_SMTP, "jitter", xml_handle_seconds, ctx,
+       register_worker_opt (type, "jitter", xml_handle_seconds, ctx,
                                                G_STRUCT_OFFSET (struct smtp_worker_ctx, delay_jitter));
-       register_worker_opt (TYPE_SMTP, "capabilities", xml_handle_string, ctx,
+       register_worker_opt (type, "capabilities", xml_handle_string, ctx,
                                        G_STRUCT_OFFSET (struct smtp_worker_ctx, smtp_capabilities_str));
-       register_worker_opt (TYPE_SMTP, "xclient", xml_handle_boolean, ctx,
+       register_worker_opt (type, "xclient", xml_handle_boolean, ctx,
                                        G_STRUCT_OFFSET (struct smtp_worker_ctx, use_xclient));
-       register_worker_opt (TYPE_SMTP, "reject_message", xml_handle_string, ctx,
+       register_worker_opt (type, "reject_message", xml_handle_string, ctx,
                                                G_STRUCT_OFFSET (struct smtp_worker_ctx, reject_message));
-       register_worker_opt (TYPE_SMTP, "max_errors", xml_handle_uint32, ctx,
+       register_worker_opt (type, "max_errors", xml_handle_uint32, ctx,
                                                G_STRUCT_OFFSET (struct smtp_worker_ctx, max_errors));
-       register_worker_opt (TYPE_SMTP, "max_size", xml_handle_size, ctx,
+       register_worker_opt (type, "max_size", xml_handle_size, ctx,
                                                G_STRUCT_OFFSET (struct smtp_worker_ctx, max_size));
 
        return ctx;
@@ -984,7 +1000,7 @@ config_smtp_worker (struct rspamd_worker *worker)
  * Start worker process
  */
 void
-start_smtp_worker (struct rspamd_worker *worker)
+start_smtp (struct rspamd_worker *worker)
 {
        struct sigaction                signals;
        struct smtp_worker_ctx         *ctx = worker->ctx;
index 00d8c3abfac32a635feabfc088218949ecde9820..d2c14f924e6d7b6586a17d65b5d0cae4f64eae84 100644 (file)
@@ -121,16 +121,6 @@ struct smtp_filter {
        gpointer filter_data;
 };
 
-/*
- * Perform initialization of SMTP worker
- */
-gpointer init_smtp_worker (void);
-
-/*
- * Start SMTP worker
- */
-void start_smtp_worker (struct rspamd_worker *worker);
-
 /*
  * Register new SMTP filter
  * XXX: work is still in progress
index 23203255b4a9015eab26b8b3555506660a21b199..5fcf0858b03a9cb47b3ad8a5778f035f020cdb83 100644 (file)
@@ -1161,57 +1161,6 @@ rspamd_strlcpy (gchar *dst, const gchar *src, gsize siz)
        return (s - src - 1);    /* count does not include NUL */
 }
 
-/* Convert process type to its name */
-const gchar              *
-process_to_str (enum process_type type)
-{
-       switch (type) {
-       case TYPE_MAIN:
-               return "main";
-       case TYPE_WORKER:
-               return "worker";
-       case TYPE_FUZZY:
-               return "fuzzy";
-       case TYPE_CONTROLLER:
-               return "controller";
-       case TYPE_LMTP:
-               return "lmtp";
-       case TYPE_SMTP:
-               return "smtp";
-       case TYPE_KVSTORAGE:
-               return "keystorage";
-       default:
-               return "unknown";
-       }
-
-       return NULL;
-}
-/* Convert string to process type */
-enum process_type
-str_to_process (const gchar *str)
-{
-       if (g_ascii_strcasecmp (str, "main") == 0) {
-               return TYPE_MAIN;
-       }
-       else if (g_ascii_strcasecmp (str, "worker") == 0) {
-               return TYPE_WORKER;
-       }
-       else if (g_ascii_strcasecmp (str, "fuzzy") == 0) {
-               return TYPE_FUZZY;
-       }
-       else if (g_ascii_strcasecmp (str, "controller") == 0) {
-               return TYPE_CONTROLLER;
-       }
-       else if (g_ascii_strcasecmp (str, "smtp") == 0) {
-               return TYPE_SMTP;
-       }
-       else if (g_ascii_strcasecmp (str, "lmtp") == 0) {
-               return TYPE_LMTP;
-       }
-
-       return TYPE_UNKNOWN;
-}
-
 /* Compare two emails for building emails tree */
 gint
 compare_email_func (gconstpointer a, gconstpointer b)
@@ -1396,6 +1345,29 @@ rspamd_fallocate (gint fd, off_t offset, off_t len)
 #endif
 }
 
+
+/**
+ * Return worker's control structure by its type
+ * @param type
+ * @return worker's control structure or NULL
+ */
+worker_t*
+get_worker_by_type (GQuark type)
+{
+       worker_t                                                **cur;
+
+       cur = &workers[0];
+       while (*cur) {
+               if (g_quark_from_string ((*cur)->name) == type) {
+                       return *cur;
+               }
+               cur ++;
+       }
+
+       return NULL;
+}
+
+
 /*
  * vi:ts=4
  */
index c4fcc80f403d76c57fa1b689d6970eac6d9ea48b..e520c9d2d79bbe881a1feb5b4d14157a1519d835 100644 (file)
@@ -14,21 +14,6 @@ struct workq;
 struct statfile;
 struct classifier_config;
 
-/**
- * Process type: main or worker
- */
-enum process_type {
-       TYPE_UNKNOWN=-1,
-       TYPE_MAIN,
-       TYPE_WORKER,
-       TYPE_CONTROLLER,
-       TYPE_LMTP,
-       TYPE_SMTP,
-       TYPE_FUZZY,
-       TYPE_KVSTORAGE,
-       TYPE_MAX=255
-};
-
 /*
  * Create socket and bind or connect it to specified address and port
  */
@@ -194,21 +179,6 @@ void g_queue_clear (GQueue *queue);
  */
 gsize rspamd_strlcpy (gchar *dst, const gchar *src, gsize siz);
 
-/*
- * Convert process type to its name
- *
- * @param type numeric type
- * @return string representation of type
- */
-const gchar * process_to_str (enum process_type type);
-/*
- * Convert string to process type
- *
- * @param type numeric type
- * @return string representation of type
- */
-enum process_type str_to_process (const gchar *str);
-
 /*
  * Strip <> from email address
  */
@@ -250,4 +220,11 @@ gboolean rspamd_strtoul (const gchar *s, gsize len, gulong *value);
  */
 gint rspamd_fallocate (gint fd, off_t offset, off_t len);
 
+/**
+ * Return worker's control structure by its type
+ * @param type
+ * @return worker's control structure or NULL
+ */
+worker_t* get_worker_by_type (GQuark type);
+
 #endif
index 151045c195177c20b88e68dc37d27b390029a958..48f4d19367094c7fd08513bfb0323862c39fe9c3 100644 (file)
@@ -34,7 +34,6 @@
 #include "cfg_file.h"
 #include "cfg_xml.h"
 #include "url.h"
-#include "modules.h"
 #include "message.h"
 #include "map.h"
 #include "dns.h"
 /* 60 seconds for worker's IO */
 #define DEFAULT_WORKER_IO_TIMEOUT 60000
 
+gpointer init_worker (void);
+void start_worker (struct rspamd_worker *worker);
+
+worker_t normal_worker = {
+       "normal",                                       /* Name */
+       init_worker,                            /* Init function */
+       start_worker,                           /* Start function */
+       TRUE,                                           /* Has socket */
+       FALSE,                                          /* Non unique */
+       FALSE,                                          /* Non threaded */
+       TRUE                                            /* Killable */
+};
+
 #ifndef BUILD_STATIC
 
 #define MODULE_INIT_FUNC "module_init"
@@ -822,18 +834,21 @@ gpointer
 init_worker (void)
 {
        struct rspamd_worker_ctx       *ctx;
+       GQuark                                                          type;
+
+       type = g_quark_try_string ("normal");
 
        ctx = g_malloc0 (sizeof (struct rspamd_worker_ctx));
 
        ctx->is_mime = TRUE;
        ctx->timeout = DEFAULT_WORKER_IO_TIMEOUT;
 
-       register_worker_opt (TYPE_WORKER, "mime", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, is_mime));
-       register_worker_opt (TYPE_WORKER, "http", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, is_http));
-       register_worker_opt (TYPE_WORKER, "json", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, is_json));
-       register_worker_opt (TYPE_WORKER, "allow_learn", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, allow_learn));
-       register_worker_opt (TYPE_WORKER, "timeout", xml_handle_seconds, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, timeout));
-       register_worker_opt (TYPE_WORKER, "max_tasks", xml_handle_uint32, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, max_tasks));
+       register_worker_opt (type, "mime", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, is_mime));
+       register_worker_opt (type, "http", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, is_http));
+       register_worker_opt (type, "json", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, is_json));
+       register_worker_opt (type, "allow_learn", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, allow_learn));
+       register_worker_opt (type, "timeout", xml_handle_seconds, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, timeout));
+       register_worker_opt (type, "max_tasks", xml_handle_uint32, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, max_tasks));
 
        return ctx;
 }