- 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.tags/0.4.7
@@ -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") |
@@ -433,14 +433,26 @@ | |||
/* 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 |
@@ -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 */ |
@@ -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 */ |
@@ -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); |
@@ -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" | |||
@@ -44,6 +43,20 @@ | |||
/* 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; | |||
} |
@@ -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" | |||
@@ -63,6 +62,20 @@ | |||
/* 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 (); | |||
@@ -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 |
@@ -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; |
@@ -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_ */ |
@@ -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 */ |
@@ -15,6 +15,4 @@ | |||
#define LMTP_NO_RCPT 554 | |||
#define LMTP_TEMP_FAIL 421 | |||
void start_lmtp_worker (struct rspamd_worker *worker); | |||
#endif |
@@ -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) { |
@@ -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 |
@@ -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); |
@@ -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 | |||
*/ |
@@ -42,6 +42,18 @@ | |||
#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; |
@@ -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) |
@@ -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) | |||
{ |
@@ -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) | |||
{ |
@@ -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) | |||
{ |
@@ -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; |
@@ -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 |
@@ -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 | |||
*/ |
@@ -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 |
@@ -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" | |||
@@ -48,6 +47,19 @@ | |||
/* 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; | |||
} |