summaryrefslogtreecommitdiffstats
path: root/src/rspamd.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/rspamd.h')
-rw-r--r--src/rspamd.h378
1 files changed, 378 insertions, 0 deletions
diff --git a/src/rspamd.h b/src/rspamd.h
new file mode 100644
index 0000000..523ea79
--- /dev/null
+++ b/src/rspamd.h
@@ -0,0 +1,378 @@
+/*
+ * Copyright 2023 Vsevolod Stakhov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSPAMD_MAIN_H
+#define RSPAMD_MAIN_H
+
+#include "config.h"
+#include "libutil/fstring.h"
+#include "libutil/mem_pool.h"
+#include "libutil/util.h"
+#include "libserver/logger.h"
+#include "libserver/http/http_connection.h"
+#include "libutil/upstream.h"
+#include "libutil/radix.h"
+#include "libserver/cfg_file.h"
+#include "libserver/url.h"
+#include "libserver/protocol.h"
+#include "libserver/async_session.h"
+#include "libserver/roll_history.h"
+#include "libserver/task.h"
+
+#include <openssl/ssl.h>
+
+/* Default values */
+#define FIXED_CONFIG_FILE RSPAMD_CONFDIR "/rspamd.conf"
+/* Time in seconds to exit for old worker */
+#define SOFT_SHUTDOWN_TIME 10
+
+/* Spam subject */
+#define SPAM_SUBJECT "*** SPAM *** %s"
+
+#ifdef CRLF
+#undef CRLF
+#undef CR
+#undef LF
+#endif
+
+#define CRLF "\r\n"
+#define CR '\r'
+#define LF '\n'
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct rspamd_main;
+
+enum rspamd_worker_flags {
+ RSPAMD_WORKER_HAS_SOCKET = (1 << 0),
+ RSPAMD_WORKER_UNIQUE = (1 << 1),
+ RSPAMD_WORKER_THREADED = (1 << 2),
+ RSPAMD_WORKER_KILLABLE = (1 << 3),
+ RSPAMD_WORKER_ALWAYS_START = (1 << 4),
+ RSPAMD_WORKER_SCANNER = (1 << 5),
+ RSPAMD_WORKER_CONTROLLER = (1 << 6),
+ RSPAMD_WORKER_NO_TERMINATE_DELAY = (1 << 7),
+ RSPAMD_WORKER_OLD_CONFIG = (1 << 8),
+ RSPAMD_WORKER_NO_STRICT_CONFIG = (1 << 9),
+};
+
+struct rspamd_worker_accept_event {
+ ev_io accept_ev;
+ ev_timer throttling_ev;
+ struct ev_loop *event_loop;
+ struct rspamd_worker_accept_event *prev, *next;
+};
+
+typedef void (*rspamd_worker_term_cb)(EV_P_ ev_child *, struct rspamd_main *,
+ struct rspamd_worker *);
+
+struct rspamd_worker_heartbeat {
+ ev_timer heartbeat_ev; /**< used by main for checking heartbeats and by workers to send heartbeats */
+ ev_tstamp last_event; /**< last heartbeat received timestamp */
+ gint64 nbeats; /**< positive for beats received, negative for beats missed */
+};
+
+enum rspamd_worker_state {
+ rspamd_worker_state_running = 0,
+ rspamd_worker_state_wanna_die,
+ rspamd_worker_state_terminating,
+ rspamd_worker_wait_connections,
+ rspamd_worker_wait_final_scripts,
+ rspamd_worker_wanna_die
+};
+
+/**
+ * Worker process structure
+ */
+struct rspamd_worker {
+ pid_t pid; /**< pid of worker */
+ pid_t ppid; /**< pid of parent */
+ guint index; /**< index number */
+ guint nconns; /**< current connections count */
+ enum rspamd_worker_state state; /**< current worker state */
+ gboolean cores_throttled; /**< set to true if cores throttling took place */
+ gdouble start_time; /**< start time */
+ struct rspamd_main *srv; /**< pointer to server structure */
+ GQuark type; /**< process type */
+ GHashTable *signal_events; /**< signal events */
+ struct rspamd_worker_accept_event *accept_events; /**< socket events */
+ struct rspamd_worker_conf *cf; /**< worker config data */
+ gpointer ctx; /**< worker's specific data */
+ gint flags; /**< worker's flags (enum rspamd_worker_flags) */
+ gint control_pipe[2]; /**< control pipe. [0] is used by main process,
+ [1] is used by a worker */
+ gint srv_pipe[2]; /**< used by workers to request something from the
+ main process. [0] - main, [1] - worker */
+ ev_io srv_ev; /**< used by main for read workers' requests */
+ struct rspamd_worker_heartbeat hb; /**< heartbeat data */
+ gpointer control_data; /**< used by control protocol to handle commands */
+ gpointer tmp_data; /**< used to avoid race condition to deal with control messages */
+ ev_child cld_ev; /**< to allow reaping */
+ rspamd_worker_term_cb term_handler; /**< custom term handler */
+ GHashTable *control_events_pending; /**< control events pending indexed by ptr */
+};
+
+struct rspamd_abstract_worker_ctx {
+ guint64 magic;
+ /* Events base */
+ struct ev_loop *event_loop;
+ /* DNS resolver */
+ struct rspamd_dns_resolver *resolver;
+ /* Config */
+ struct rspamd_config *cfg;
+ char data[];
+};
+
+struct rspamd_worker_signal_handler;
+
+typedef gboolean (*rspamd_worker_signal_cb_t)(
+ struct rspamd_worker_signal_handler *, void *ud);
+
+struct rspamd_worker_signal_handler_elt {
+ rspamd_worker_signal_cb_t handler;
+ void *handler_data;
+ struct rspamd_worker_signal_handler_elt *next, *prev;
+};
+
+struct rspamd_worker_signal_handler {
+ gint signo;
+ gboolean enabled;
+ ev_signal ev_sig;
+ struct ev_loop *event_loop;
+ struct rspamd_worker *worker;
+ struct rspamd_worker_signal_handler_elt *cb;
+};
+
+/**
+ * Common structure representing C module context
+ */
+struct module_s;
+
+struct module_ctx {
+ gint (*filter)(struct rspamd_task *task); /**< pointer to headers process function */
+ struct module_s *mod; /**< module pointer */
+ gboolean enabled; /**< true if module is enabled in configuration */
+};
+
+#ifndef WITH_HYPERSCAN
+#define RSPAMD_FEATURE_HYPERSCAN "0"
+#else
+#define RSPAMD_FEATURE_HYPERSCAN "1"
+#endif
+#ifndef WITH_PCRE2
+#define RSPAMD_FEATURE_PCRE2 "0"
+#else
+#define RSPAMD_FEATURE_PCRE2 "1"
+#endif
+#ifndef WITH_FANN
+#define RSPAMD_FEATURE_FANN "0"
+#else
+#define RSPAMD_FEATURE_FANN "1"
+#endif
+#ifndef WITH_SNOWBALL
+#define RSPAMD_FEATURE_SNOWBALL "0"
+#else
+#define RSPAMD_FEATURE_SNOWBALL "1"
+#endif
+
+#define RSPAMD_CUR_MODULE_VERSION 0x1
+#define RSPAMD_CUR_WORKER_VERSION 0x2
+
+#define RSPAMD_FEATURES \
+ RSPAMD_FEATURE_HYPERSCAN RSPAMD_FEATURE_PCRE2 \
+ RSPAMD_FEATURE_FANN RSPAMD_FEATURE_SNOWBALL
+
+#define RSPAMD_MODULE_VER \
+ RSPAMD_CUR_MODULE_VERSION, /* Module version */ \
+ RSPAMD_VERSION_NUM, /* Rspamd version */ \
+ RSPAMD_FEATURES /* Compilation features */
+
+#define RSPAMD_WORKER_VER \
+ RSPAMD_CUR_WORKER_VERSION, /* Worker version */ \
+ RSPAMD_VERSION_NUM, /* Rspamd version */ \
+ RSPAMD_FEATURES /* Compilation features */ /**
+ * Module
+ */
+typedef struct module_s {
+ const gchar *name;
+
+ int (*module_init_func)(struct rspamd_config *cfg, struct module_ctx **ctx);
+
+ int (*module_config_func)(struct rspamd_config *cfg, bool validate);
+
+ int (*module_reconfig_func)(struct rspamd_config *cfg);
+
+ int (*module_attach_controller_func)(struct module_ctx *ctx,
+ GHashTable *custom_commands);
+
+ guint module_version;
+ guint64 rspamd_version;
+ const gchar *rspamd_features;
+ guint ctx_offset;
+} module_t;
+
+enum rspamd_worker_socket_type {
+ RSPAMD_WORKER_SOCKET_NONE = 0,
+ RSPAMD_WORKER_SOCKET_TCP = (1 << 0),
+ RSPAMD_WORKER_SOCKET_UDP = (1 << 1),
+};
+
+struct rspamd_worker_listen_socket {
+ const rspamd_inet_addr_t *addr;
+ gint fd;
+ enum rspamd_worker_socket_type type;
+ bool is_systemd;
+};
+
+typedef struct worker_s {
+ const gchar *name;
+
+ gpointer (*worker_init_func)(struct rspamd_config *cfg);
+
+ void (*worker_start_func)(struct rspamd_worker *worker);
+
+ int flags;
+ int listen_type;
+ guint worker_version;
+ guint64 rspamd_version;
+ const gchar *rspamd_features;
+} worker_t;
+
+/**
+ * Check if loaded worker is compatible with rspamd
+ * @param cfg
+ * @param wrk
+ * @return
+ */
+gboolean rspamd_check_worker(struct rspamd_config *cfg, worker_t *wrk);
+
+/**
+ * Check if loaded module is compatible with rspamd
+ * @param cfg
+ * @param wrk
+ * @return
+ */
+gboolean rspamd_check_module(struct rspamd_config *cfg, module_t *wrk);
+
+struct pidfh;
+struct rspamd_config;
+struct tokenizer;
+struct rspamd_stat_classifier;
+struct rspamd_classifier_config;
+struct rspamd_mime_part;
+struct rspamd_dns_resolver;
+struct rspamd_task;
+struct rspamd_cryptobox_library_ctx;
+
+#define MAX_AVG_TIME_SLOTS 31
+struct RSPAMD_ALIGNED(64) rspamd_avg_time {
+ guint32 cur_slot;
+ float avg_time[MAX_AVG_TIME_SLOTS];
+};
+/**
+ * Server statistics
+ */
+struct RSPAMD_ALIGNED(64) rspamd_stat {
+ guint messages_scanned; /**< total number of messages scanned */
+ guint actions_stat[METRIC_ACTION_MAX]; /**< statistic for each action */
+ guint connections_count; /**< total connections count */
+ guint control_connections_count; /**< connections count to control interface */
+ guint messages_learned; /**< messages learned */
+ struct rspamd_avg_time avg_time; /**< average time stats */
+};
+
+/**
+ * Struct that determine main server object (for logging purposes)
+ */
+struct rspamd_main {
+ struct rspamd_config *cfg; /**< pointer to config structure */
+ pid_t pid; /**< main pid */
+ /* Pid file structure */
+ rspamd_pidfh_t *pfh; /**< struct pidfh for pidfile */
+ GQuark type; /**< process type */
+ struct rspamd_stat *stat; /**< pointer to statistics */
+
+ rspamd_mempool_t *server_pool; /**< server's memory pool */
+ rspamd_mempool_mutex_t *start_mtx; /**< server is starting up */
+ GHashTable *workers; /**< workers pool indexed by pid */
+ GHashTable *spairs; /**< socket pairs requested by workers */
+ rspamd_logger_t *logger;
+ uid_t workers_uid; /**< worker's uid running to */
+ gid_t workers_gid; /**< worker's gid running to */
+ gboolean is_privileged; /**< true if run in privileged mode */
+ gboolean wanna_die; /**< no respawn of processes */
+ gboolean cores_throttling; /**< turn off cores when limits are exceeded */
+ struct roll_history *history; /**< rolling history */
+ struct ev_loop *event_loop;
+ ev_signal term_ev, int_ev, hup_ev, usr1_ev; /**< signals */
+ struct rspamd_http_context *http_ctx;
+};
+
+/**
+ * Control session object
+ */
+struct controller_command;
+struct controller_session;
+
+typedef gboolean (*controller_func_t)(gchar **args,
+ struct controller_session *session);
+
+struct controller_session {
+ struct rspamd_worker *worker; /**< pointer to worker structure (controller in fact) */
+ gint sock; /**< socket descriptor */
+ struct controller_command *cmd; /**< real command */
+ struct rspamd_config *cfg; /**< pointer to config file */
+ GList *parts; /**< extracted mime parts */
+ struct rspamd_async_session *s; /**< async session object */
+ struct rspamd_dns_resolver *resolver; /**< DNS resolver */
+ struct ev_loop *ev_base; /**< Event base */
+};
+
+struct zstd_dictionary {
+ void *dict;
+ gsize size;
+ guint id;
+};
+
+struct rspamd_external_libs_ctx {
+ void **local_addrs;
+ struct rspamd_cryptobox_library_ctx *crypto_ctx;
+ struct ottery_config *ottery_cfg;
+ void *ssl_ctx;
+ void *ssl_ctx_noverify;
+ struct zstd_dictionary *in_dict;
+ struct zstd_dictionary *out_dict;
+ void *out_zstream;
+ void *in_zstream;
+ ref_entry_t ref;
+};
+
+
+/**
+ * Register custom controller function
+ */
+void register_custom_controller_command(const gchar *name,
+ controller_func_t handler,
+ gboolean privileged,
+ gboolean require_message);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif \ No newline at end of file