1 /*- 2 * Copyright 2016 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 WORKER_UTIL_H_ 17 #define WORKER_UTIL_H_ 18 19 #include "config.h" 20 #include "util.h" 21 #include "libserver/http/http_connection.h" 22 #include "rspamd.h" 23 24 #ifdef __cplusplus 25 extern "C" { 26 #endif 27 28 #ifndef HAVE_SA_SIGINFO 29 typedef void (*rspamd_sig_handler_t) (gint); 30 #else 31 32 typedef void (*rspamd_sig_handler_t) (gint, siginfo_t *, void *); 33 34 #endif 35 36 struct rspamd_worker; 37 struct rspamd_worker_signal_handler; 38 39 /** 40 * Init basic signals for a worker 41 * @param worker 42 * @param event_loop 43 */ 44 void rspamd_worker_init_signals (struct rspamd_worker *worker, struct ev_loop *event_loop); 45 46 typedef void (*rspamd_accept_handler) (struct ev_loop *loop, ev_io *w, int revents); 47 48 /** 49 * Prepare worker's startup 50 * @param worker worker structure 51 * @param name name of the worker 52 * @param sig_handler handler of main signals 53 * @param accept_handler handler of accept event for listen sockets 54 * @return event base suitable for a worker 55 */ 56 struct ev_loop * 57 rspamd_prepare_worker (struct rspamd_worker *worker, const char *name, 58 rspamd_accept_handler hdl); 59 60 /** 61 * Should be used to validate context for a worker as in assert like invocation 62 * @param ctx 63 * @param magic 64 * @return 65 */ 66 gboolean rspamd_worker_check_context (gpointer ctx, guint64 magic); 67 68 /** 69 * Set special signal handler for a worker 70 */ 71 void rspamd_worker_set_signal_handler (int signo, 72 struct rspamd_worker *worker, 73 struct ev_loop *event_loop, 74 rspamd_worker_signal_cb_t handler, 75 void *handler_data); 76 77 /** 78 * Stop accepting new connections for a worker 79 * @param worker 80 */ 81 void rspamd_worker_stop_accept (struct rspamd_worker *worker); 82 83 typedef gint (*rspamd_controller_func_t) ( 84 struct rspamd_http_connection_entry *conn_ent, 85 struct rspamd_http_message *msg, 86 struct module_ctx *ctx); 87 88 struct rspamd_custom_controller_command { 89 const gchar *command; 90 struct module_ctx *ctx; 91 gboolean privilleged; 92 gboolean require_message; 93 rspamd_controller_func_t handler; 94 }; 95 96 struct rspamd_controller_worker_ctx; 97 struct rspamd_lang_detector; 98 99 struct rspamd_controller_session { 100 struct rspamd_controller_worker_ctx *ctx; 101 struct rspamd_worker *wrk; 102 rspamd_mempool_t *pool; 103 struct rspamd_task *task; 104 gchar *classifier; 105 rspamd_inet_addr_t *from_addr; 106 struct rspamd_config *cfg; 107 struct rspamd_lang_detector *lang_det; 108 gboolean is_spam; 109 gboolean is_enable; 110 }; 111 112 /** 113 * Send error using HTTP and JSON output 114 * @param entry router entry 115 * @param code error code 116 * @param error_msg error message 117 */ 118 void rspamd_controller_send_error (struct rspamd_http_connection_entry *entry, 119 gint code, const gchar *error_msg, ...); 120 121 /** 122 * Send openmetrics-formatted strings using HTTP 123 * @param entry router entry 124 * @param str rspamd fstring buffer, ownership is transferred 125 */ 126 void 127 rspamd_controller_send_openmetrics (struct rspamd_http_connection_entry *entry, 128 rspamd_fstring_t *str); 129 130 /** 131 * Send a custom string using HTTP 132 * @param entry router entry 133 * @param str string to send 134 */ 135 void rspamd_controller_send_string (struct rspamd_http_connection_entry *entry, 136 const gchar *str); 137 138 /** 139 * Send UCL using HTTP and JSON serialization 140 * @param entry router entry 141 * @param obj object to send 142 */ 143 void rspamd_controller_send_ucl (struct rspamd_http_connection_entry *entry, 144 ucl_object_t *obj); 145 146 /** 147 * Return worker's control structure by its type 148 * @param type 149 * @return worker's control structure or NULL 150 */ 151 worker_t *rspamd_get_worker_by_type (struct rspamd_config *cfg, GQuark type); 152 153 /** 154 * Block signals before terminations 155 */ 156 void rspamd_worker_block_signals (void); 157 158 /** 159 * Unblock signals 160 */ 161 void rspamd_worker_unblock_signals (void); 162 163 /** 164 * Kill rspamd main and all workers 165 * @param rspamd_main 166 */ 167 void rspamd_hard_terminate (struct rspamd_main *rspamd_main) G_GNUC_NORETURN; 168 169 /** 170 * Returns TRUE if a specific worker is a scanner worker 171 * @param w 172 * @return 173 */ 174 gboolean rspamd_worker_is_scanner (struct rspamd_worker *w); 175 176 /** 177 * Returns TRUE if a specific worker is a primary controller 178 * @param w 179 * @return 180 */ 181 gboolean rspamd_worker_is_primary_controller (struct rspamd_worker *w); 182 183 /** 184 * Creates new session cache 185 * @param w 186 * @return 187 */ 188 void *rspamd_worker_session_cache_new (struct rspamd_worker *w, 189 struct ev_loop *ev_base); 190 191 /** 192 * Adds a new session identified by pointer 193 * @param cache 194 * @param tag 195 * @param pref 196 * @param ptr 197 */ 198 void rspamd_worker_session_cache_add (void *cache, const gchar *tag, 199 guint *pref, void *ptr); 200 201 /** 202 * Removes session from cache 203 * @param cache 204 * @param ptr 205 */ 206 void rspamd_worker_session_cache_remove (void *cache, void *ptr); 207 208 /** 209 * Fork new worker with the specified configuration 210 */ 211 struct rspamd_worker *rspamd_fork_worker (struct rspamd_main *, 212 struct rspamd_worker_conf *, guint idx, 213 struct ev_loop *ev_base, 214 rspamd_worker_term_cb term_handler, 215 GHashTable *listen_sockets); 216 217 /** 218 * Sets crash signals handlers if compiled with libunwind 219 */ 220 RSPAMD_NO_SANITIZE void rspamd_set_crash_handler (struct rspamd_main *); 221 222 /** 223 * Initialise the main monitoring worker 224 * @param worker 225 * @param ev_base 226 * @param resolver 227 */ 228 void rspamd_worker_init_monitored (struct rspamd_worker *worker, 229 struct ev_loop *ev_base, 230 struct rspamd_dns_resolver *resolver); 231 232 /** 233 * Performs throttling for accept events 234 * @param sock 235 * @param data struct rspamd_worker_accept_event * list 236 */ 237 void rspamd_worker_throttle_accept_events (gint sock, void *data); 238 239 /** 240 * Checks (and logs) the worker's termination status. Returns TRUE if a worker 241 * should be restarted. 242 * @param rspamd_main 243 * @param wrk 244 * @param status waitpid res 245 * @return TRUE if refork is desired 246 */ 247 gboolean rspamd_check_termination_clause (struct rspamd_main *rspamd_main, 248 struct rspamd_worker *wrk, int status); 249 250 /** 251 * Call for final scripts for a worker 252 * @param worker 253 * @return 254 */ 255 gboolean rspamd_worker_call_finish_handlers (struct rspamd_worker *worker); 256 257 struct rspamd_rrd_file; 258 /** 259 * Terminate controller worker 260 * @param worker 261 */ 262 void rspamd_controller_on_terminate (struct rspamd_worker *worker, 263 struct rspamd_rrd_file *rrd); 264 265 /** 266 * Inits controller worker 267 * @param worker 268 * @param ev_base 269 * @param prrd 270 */ 271 void rspamd_worker_init_controller (struct rspamd_worker *worker, 272 struct rspamd_rrd_file **prrd); 273 274 /** 275 * Saves stats 276 * @param rspamd_main 277 * @param cfg 278 */ 279 void rspamd_controller_store_saved_stats (struct rspamd_main *rspamd_main, 280 struct rspamd_config *cfg); 281 282 #ifdef WITH_HYPERSCAN 283 struct rspamd_control_command; 284 285 gboolean rspamd_worker_hyperscan_ready (struct rspamd_main *rspamd_main, 286 struct rspamd_worker *worker, gint fd, 287 gint attached_fd, 288 struct rspamd_control_command *cmd, 289 gpointer ud); 290 291 #endif 292 293 #define msg_err_main(...) rspamd_default_log_function (G_LOG_LEVEL_CRITICAL, \ 294 rspamd_main->server_pool->tag.tagname, rspamd_main->server_pool->tag.uid, \ 295 RSPAMD_LOG_FUNC, \ 296 __VA_ARGS__) 297 #define msg_warn_main(...) rspamd_default_log_function (G_LOG_LEVEL_WARNING, \ 298 rspamd_main->server_pool->tag.tagname, rspamd_main->server_pool->tag.uid, \ 299 RSPAMD_LOG_FUNC, \ 300 __VA_ARGS__) 301 #define msg_notice_main(...) rspamd_default_log_function (G_LOG_LEVEL_MESSAGE, \ 302 rspamd_main->server_pool->tag.tagname, rspamd_main->server_pool->tag.uid, \ 303 RSPAMD_LOG_FUNC, \ 304 __VA_ARGS__) 305 #define msg_info_main(...) rspamd_default_log_function (G_LOG_LEVEL_INFO, \ 306 rspamd_main->server_pool->tag.tagname, rspamd_main->server_pool->tag.uid, \ 307 RSPAMD_LOG_FUNC, \ 308 __VA_ARGS__) 309 310 #ifdef __cplusplus 311 } 312 #endif 313 314 #endif /* WORKER_UTIL_H_ */ 315