You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rspamd.h 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /*
  2. * Copyright 2024 Vsevolod Stakhov
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef RSPAMD_MAIN_H
  17. #define RSPAMD_MAIN_H
  18. #include "config.h"
  19. #include "libutil/fstring.h"
  20. #include "libutil/mem_pool.h"
  21. #include "libutil/util.h"
  22. #include "libserver/logger.h"
  23. #include "libserver/http/http_connection.h"
  24. #include "libutil/upstream.h"
  25. #include "libutil/radix.h"
  26. #include "libserver/cfg_file.h"
  27. #include "libserver/url.h"
  28. #include "libserver/protocol.h"
  29. #include "libserver/async_session.h"
  30. #include "libserver/roll_history.h"
  31. #include "libserver/task.h"
  32. #include <openssl/ssl.h>
  33. /* Default values */
  34. #define FIXED_CONFIG_FILE RSPAMD_CONFDIR "/rspamd.conf"
  35. /* Time in seconds to exit for old worker */
  36. #define SOFT_SHUTDOWN_TIME 10
  37. /* Spam subject */
  38. #define SPAM_SUBJECT "*** SPAM *** %s"
  39. #ifdef CRLF
  40. #undef CRLF
  41. #undef CR
  42. #undef LF
  43. #endif
  44. #define CRLF "\r\n"
  45. #define CR '\r'
  46. #define LF '\n'
  47. #ifdef __cplusplus
  48. extern "C" {
  49. #endif
  50. struct rspamd_main;
  51. enum rspamd_worker_flags {
  52. RSPAMD_WORKER_HAS_SOCKET = (1 << 0),
  53. RSPAMD_WORKER_UNIQUE = (1 << 1),
  54. RSPAMD_WORKER_THREADED = (1 << 2),
  55. RSPAMD_WORKER_KILLABLE = (1 << 3),
  56. RSPAMD_WORKER_ALWAYS_START = (1 << 4),
  57. RSPAMD_WORKER_SCANNER = (1 << 5),
  58. RSPAMD_WORKER_CONTROLLER = (1 << 6),
  59. RSPAMD_WORKER_NO_TERMINATE_DELAY = (1 << 7),
  60. RSPAMD_WORKER_OLD_CONFIG = (1 << 8),
  61. RSPAMD_WORKER_NO_STRICT_CONFIG = (1 << 9),
  62. };
  63. struct rspamd_worker_accept_event {
  64. ev_io accept_ev;
  65. ev_timer throttling_ev;
  66. struct ev_loop *event_loop;
  67. struct rspamd_worker_accept_event *prev, *next;
  68. };
  69. typedef void (*rspamd_worker_term_cb)(EV_P_ ev_child *, struct rspamd_main *,
  70. struct rspamd_worker *);
  71. struct rspamd_worker_heartbeat {
  72. ev_timer heartbeat_ev; /**< used by main for checking heartbeats and by workers to send heartbeats */
  73. ev_tstamp last_event; /**< last heartbeat received timestamp */
  74. int64_t nbeats; /**< positive for beats received, negative for beats missed */
  75. };
  76. enum rspamd_worker_state {
  77. rspamd_worker_state_running = 0,
  78. rspamd_worker_state_wanna_die,
  79. rspamd_worker_state_terminating,
  80. rspamd_worker_wait_connections,
  81. rspamd_worker_wait_final_scripts,
  82. rspamd_worker_wanna_die
  83. };
  84. /**
  85. * Worker process structure
  86. */
  87. struct rspamd_worker {
  88. pid_t pid; /**< pid of worker */
  89. pid_t ppid; /**< pid of parent */
  90. unsigned int index; /**< index number */
  91. unsigned int nconns; /**< current connections count */
  92. enum rspamd_worker_state state; /**< current worker state */
  93. gboolean cores_throttled; /**< set to true if cores throttling took place */
  94. double start_time; /**< start time */
  95. struct rspamd_main *srv; /**< pointer to server structure */
  96. GQuark type; /**< process type */
  97. GHashTable *signal_events; /**< signal events */
  98. struct rspamd_worker_accept_event *accept_events; /**< socket events */
  99. struct rspamd_worker_conf *cf; /**< worker config data */
  100. gpointer ctx; /**< worker's specific data */
  101. int flags; /**< worker's flags (enum rspamd_worker_flags) */
  102. int control_pipe[2]; /**< control pipe. [0] is used by main process,
  103. [1] is used by a worker */
  104. int srv_pipe[2]; /**< used by workers to request something from the
  105. main process. [0] - main, [1] - worker */
  106. ev_io srv_ev; /**< used by main for read workers' requests */
  107. struct rspamd_worker_heartbeat hb; /**< heartbeat data */
  108. gpointer control_data; /**< used by control protocol to handle commands */
  109. gpointer tmp_data; /**< used to avoid race condition to deal with control messages */
  110. ev_child cld_ev; /**< to allow reaping */
  111. rspamd_worker_term_cb term_handler; /**< custom term handler */
  112. GHashTable *control_events_pending; /**< control events pending indexed by ptr */
  113. };
  114. struct rspamd_abstract_worker_ctx {
  115. uint64_t magic;
  116. /* Events base */
  117. struct ev_loop *event_loop;
  118. /* DNS resolver */
  119. struct rspamd_dns_resolver *resolver;
  120. /* Config */
  121. struct rspamd_config *cfg;
  122. char data[];
  123. };
  124. struct rspamd_worker_signal_handler;
  125. typedef gboolean (*rspamd_worker_signal_cb_t)(
  126. struct rspamd_worker_signal_handler *, void *ud);
  127. struct rspamd_worker_signal_handler_elt {
  128. rspamd_worker_signal_cb_t handler;
  129. void *handler_data;
  130. struct rspamd_worker_signal_handler_elt *next, *prev;
  131. };
  132. struct rspamd_worker_signal_handler {
  133. int signo;
  134. gboolean enabled;
  135. ev_signal ev_sig;
  136. struct ev_loop *event_loop;
  137. struct rspamd_worker *worker;
  138. struct rspamd_worker_signal_handler_elt *cb;
  139. };
  140. /**
  141. * Common structure representing C module context
  142. */
  143. struct module_s;
  144. struct module_ctx {
  145. int (*filter)(struct rspamd_task *task); /**< pointer to headers process function */
  146. struct module_s *mod; /**< module pointer */
  147. gboolean enabled; /**< true if module is enabled in configuration */
  148. };
  149. #ifndef WITH_HYPERSCAN
  150. #define RSPAMD_FEATURE_HYPERSCAN "0"
  151. #else
  152. #define RSPAMD_FEATURE_HYPERSCAN "1"
  153. #endif
  154. #ifndef WITH_PCRE2
  155. #define RSPAMD_FEATURE_PCRE2 "0"
  156. #else
  157. #define RSPAMD_FEATURE_PCRE2 "1"
  158. #endif
  159. #ifndef WITH_FANN
  160. #define RSPAMD_FEATURE_FANN "0"
  161. #else
  162. #define RSPAMD_FEATURE_FANN "1"
  163. #endif
  164. #ifndef WITH_SNOWBALL
  165. #define RSPAMD_FEATURE_SNOWBALL "0"
  166. #else
  167. #define RSPAMD_FEATURE_SNOWBALL "1"
  168. #endif
  169. #define RSPAMD_CUR_MODULE_VERSION 0x1
  170. #define RSPAMD_CUR_WORKER_VERSION 0x2
  171. #define RSPAMD_FEATURES \
  172. RSPAMD_FEATURE_HYPERSCAN RSPAMD_FEATURE_PCRE2 \
  173. RSPAMD_FEATURE_FANN RSPAMD_FEATURE_SNOWBALL
  174. #define RSPAMD_MODULE_VER \
  175. RSPAMD_CUR_MODULE_VERSION, /* Module version */ \
  176. RSPAMD_VERSION_NUM, /* Rspamd version */ \
  177. RSPAMD_FEATURES /* Compilation features */
  178. #define RSPAMD_WORKER_VER \
  179. RSPAMD_CUR_WORKER_VERSION, /* Worker version */ \
  180. RSPAMD_VERSION_NUM, /* Rspamd version */ \
  181. RSPAMD_FEATURES /* Compilation features */ /**
  182. * Module
  183. */
  184. typedef struct module_s {
  185. const char *name;
  186. int (*module_init_func)(struct rspamd_config *cfg, struct module_ctx **ctx);
  187. int (*module_config_func)(struct rspamd_config *cfg, bool validate);
  188. int (*module_reconfig_func)(struct rspamd_config *cfg);
  189. int (*module_attach_controller_func)(struct module_ctx *ctx,
  190. GHashTable *custom_commands);
  191. unsigned int module_version;
  192. uint64_t rspamd_version;
  193. const char *rspamd_features;
  194. unsigned int ctx_offset;
  195. } module_t;
  196. enum rspamd_worker_socket_type {
  197. RSPAMD_WORKER_SOCKET_NONE = 0,
  198. RSPAMD_WORKER_SOCKET_TCP = (1 << 0),
  199. RSPAMD_WORKER_SOCKET_UDP = (1 << 1),
  200. };
  201. struct rspamd_worker_listen_socket {
  202. const rspamd_inet_addr_t *addr;
  203. int fd;
  204. enum rspamd_worker_socket_type type;
  205. bool is_systemd;
  206. };
  207. typedef struct worker_s {
  208. const char *name;
  209. gpointer (*worker_init_func)(struct rspamd_config *cfg);
  210. void (*worker_start_func)(struct rspamd_worker *worker);
  211. int flags;
  212. int listen_type;
  213. unsigned int worker_version;
  214. uint64_t rspamd_version;
  215. const char *rspamd_features;
  216. } worker_t;
  217. /**
  218. * Check if loaded worker is compatible with rspamd
  219. * @param cfg
  220. * @param wrk
  221. * @return
  222. */
  223. gboolean rspamd_check_worker(struct rspamd_config *cfg, worker_t *wrk);
  224. /**
  225. * Check if loaded module is compatible with rspamd
  226. * @param cfg
  227. * @param wrk
  228. * @return
  229. */
  230. gboolean rspamd_check_module(struct rspamd_config *cfg, module_t *wrk);
  231. struct pidfh;
  232. struct rspamd_config;
  233. struct tokenizer;
  234. struct rspamd_stat_classifier;
  235. struct rspamd_classifier_config;
  236. struct rspamd_mime_part;
  237. struct rspamd_dns_resolver;
  238. struct rspamd_task;
  239. struct rspamd_cryptobox_library_ctx;
  240. #define MAX_AVG_TIME_SLOTS 31
  241. struct RSPAMD_ALIGNED(64) rspamd_avg_time {
  242. uint32_t cur_slot;
  243. float avg_time[MAX_AVG_TIME_SLOTS];
  244. };
  245. /**
  246. * Server statistics
  247. */
  248. struct RSPAMD_ALIGNED(64) rspamd_stat {
  249. unsigned int messages_scanned; /**< total number of messages scanned */
  250. unsigned int actions_stat[METRIC_ACTION_MAX]; /**< statistic for each action */
  251. unsigned int connections_count; /**< total connections count */
  252. unsigned int control_connections_count; /**< connections count to control interface */
  253. unsigned int messages_learned; /**< messages learned */
  254. struct rspamd_avg_time avg_time; /**< average time stats */
  255. };
  256. /**
  257. * Struct that determine main server object (for logging purposes)
  258. */
  259. struct rspamd_main {
  260. struct rspamd_config *cfg; /**< pointer to config structure */
  261. pid_t pid; /**< main pid */
  262. /* Pid file structure */
  263. rspamd_pidfh_t *pfh; /**< struct pidfh for pidfile */
  264. GQuark type; /**< process type */
  265. struct rspamd_stat *stat; /**< pointer to statistics */
  266. rspamd_mempool_t *server_pool; /**< server's memory pool */
  267. rspamd_mempool_mutex_t *start_mtx; /**< server is starting up */
  268. GHashTable *workers; /**< workers pool indexed by pid */
  269. GHashTable *spairs; /**< socket pairs requested by workers */
  270. rspamd_logger_t *logger;
  271. uid_t workers_uid; /**< worker's uid running to */
  272. gid_t workers_gid; /**< worker's gid running to */
  273. gboolean is_privileged; /**< true if run in privileged mode */
  274. gboolean wanna_die; /**< no respawn of processes */
  275. gboolean cores_throttling; /**< turn off cores when limits are exceeded */
  276. struct roll_history *history; /**< rolling history */
  277. struct ev_loop *event_loop;
  278. ev_signal term_ev, int_ev, hup_ev, usr1_ev; /**< signals */
  279. struct rspamd_http_context *http_ctx;
  280. };
  281. /**
  282. * Control session object
  283. */
  284. struct controller_command;
  285. struct controller_session;
  286. typedef gboolean (*controller_func_t)(char **args,
  287. struct controller_session *session);
  288. struct controller_session {
  289. struct rspamd_worker *worker; /**< pointer to worker structure (controller in fact) */
  290. int sock; /**< socket descriptor */
  291. struct controller_command *cmd; /**< real command */
  292. struct rspamd_config *cfg; /**< pointer to config file */
  293. GList *parts; /**< extracted mime parts */
  294. struct rspamd_async_session *s; /**< async session object */
  295. struct rspamd_dns_resolver *resolver; /**< DNS resolver */
  296. struct ev_loop *ev_base; /**< Event base */
  297. };
  298. struct zstd_dictionary {
  299. void *dict;
  300. gsize size;
  301. unsigned int id;
  302. };
  303. struct rspamd_external_libs_ctx {
  304. void **local_addrs;
  305. struct rspamd_cryptobox_library_ctx *crypto_ctx;
  306. struct ottery_config *ottery_cfg;
  307. void *ssl_ctx;
  308. void *ssl_ctx_noverify;
  309. struct zstd_dictionary *in_dict;
  310. struct zstd_dictionary *out_dict;
  311. void *out_zstream;
  312. void *in_zstream;
  313. ref_entry_t ref;
  314. };
  315. /**
  316. * Register custom controller function
  317. */
  318. void register_custom_controller_command(const char *name,
  319. controller_func_t handler,
  320. gboolean privileged,
  321. gboolean require_message);
  322. #ifdef __cplusplus
  323. }
  324. #endif
  325. #endif