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_symcache.h 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  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 RSPAMD_SYMBOLS_CACHE_H
  17. #define RSPAMD_SYMBOLS_CACHE_H
  18. #include "config.h"
  19. #include "ucl.h"
  20. #include "cfg_file.h"
  21. #include "contrib/libev/ev.h"
  22. #include <lua.h>
  23. #ifdef __cplusplus
  24. extern "C" {
  25. #endif
  26. struct rspamd_task;
  27. struct rspamd_config;
  28. struct rspamd_symcache;
  29. struct rspamd_worker;
  30. struct rspamd_symcache_item;
  31. struct rspamd_config_settings_elt;
  32. typedef void (*symbol_func_t) (struct rspamd_task *task,
  33. struct rspamd_symcache_item *item,
  34. gpointer user_data);
  35. enum rspamd_symbol_type {
  36. SYMBOL_TYPE_NORMAL = (1u << 0u),
  37. SYMBOL_TYPE_VIRTUAL = (1u << 1u),
  38. SYMBOL_TYPE_CALLBACK = (1u << 2u),
  39. SYMBOL_TYPE_GHOST = (1u << 3u),
  40. SYMBOL_TYPE_SKIPPED = (1u << 4u),
  41. SYMBOL_TYPE_COMPOSITE = (1u << 5u),
  42. SYMBOL_TYPE_CLASSIFIER = (1u << 6u),
  43. SYMBOL_TYPE_FINE = (1u << 7u),
  44. SYMBOL_TYPE_EMPTY = (1u << 8u), /* Allow execution on empty tasks */
  45. SYMBOL_TYPE_CONNFILTER = (1u << 9u), /* Connection stage filter */
  46. SYMBOL_TYPE_PREFILTER = (1u << 10u),
  47. SYMBOL_TYPE_POSTFILTER = (1u << 11u),
  48. SYMBOL_TYPE_NOSTAT = (1u << 12u), /* Skip as statistical symbol */
  49. SYMBOL_TYPE_IDEMPOTENT = (1u << 13u), /* Symbol cannot change metric */
  50. SYMBOL_TYPE_TRIVIAL = (1u << 14u), /* Symbol is trivial */
  51. SYMBOL_TYPE_MIME_ONLY = (1u << 15u), /* Symbol is mime only */
  52. SYMBOL_TYPE_EXPLICIT_DISABLE = (1u << 16u), /* Symbol should be disabled explicitly only */
  53. SYMBOL_TYPE_IGNORE_PASSTHROUGH = (1u << 17u), /* Symbol ignores passthrough result */
  54. SYMBOL_TYPE_EXPLICIT_ENABLE = (1u << 18u), /* Symbol should be enabled explicitly only */
  55. SYMBOL_TYPE_USE_CORO = (1u << 19u), /* Symbol uses lua coroutines */
  56. };
  57. /**
  58. * Abstract structure for saving callback data for symbols
  59. */
  60. struct rspamd_abstract_callback_data {
  61. guint64 magic;
  62. char data[];
  63. };
  64. struct rspamd_symcache_item_stat {
  65. struct rspamd_counter_data time_counter;
  66. gdouble avg_time;
  67. gdouble weight;
  68. guint hits;
  69. guint64 total_hits;
  70. struct rspamd_counter_data frequency_counter;
  71. gdouble avg_frequency;
  72. gdouble stddev_frequency;
  73. };
  74. /**
  75. * Creates new cache structure
  76. * @return
  77. */
  78. struct rspamd_symcache *rspamd_symcache_new (struct rspamd_config *cfg);
  79. /**
  80. * Remove the cache structure syncing data if needed
  81. * @param cache
  82. */
  83. void rspamd_symcache_destroy (struct rspamd_symcache *cache);
  84. /**
  85. * Saves symbols cache to disk if possible
  86. * @param cache
  87. */
  88. void rspamd_symcache_save (struct rspamd_symcache *cache);
  89. /**
  90. * Load symbols cache from file, must be called _after_ init_symbols_cache
  91. */
  92. gboolean rspamd_symcache_init (struct rspamd_symcache *cache);
  93. /**
  94. * Generic function to register a symbol
  95. * @param cache
  96. * @param name
  97. * @param weight
  98. * @param priority
  99. * @param func
  100. * @param user_data
  101. * @param type
  102. * @param parent
  103. */
  104. gint rspamd_symcache_add_symbol (struct rspamd_symcache *cache,
  105. const gchar *name,
  106. gint priority,
  107. symbol_func_t func,
  108. gpointer user_data,
  109. enum rspamd_symbol_type type,
  110. gint parent);
  111. /**
  112. * Add callback to be executed whenever symbol has peak value
  113. * @param cache
  114. * @param cbref
  115. */
  116. void rspamd_symcache_set_peak_callback (struct rspamd_symcache *cache,
  117. gint cbref);
  118. /**
  119. * Add delayed condition to the specific symbol in cache. So symbol can be absent
  120. * to the moment of addition
  121. * @param cache
  122. * @param id id of symbol
  123. * @param L lua state pointer
  124. * @param cbref callback reference (returned by luaL_ref)
  125. * @return TRUE if condition has been added
  126. */
  127. gboolean rspamd_symcache_add_condition_delayed (struct rspamd_symcache *cache,
  128. const gchar *sym,
  129. lua_State *L, gint cbref);
  130. /**
  131. * Find symbol in cache by id and returns its id resolving virtual symbols if
  132. * applicable
  133. * @param cache
  134. * @param name
  135. * @return id of symbol or (-1) if a symbol has not been found
  136. */
  137. gint rspamd_symcache_find_symbol (struct rspamd_symcache *cache,
  138. const gchar *name);
  139. /**
  140. * Get statistics for a specific symbol
  141. * @param cache
  142. * @param name
  143. * @param frequency
  144. * @param tm
  145. * @return
  146. */
  147. gboolean rspamd_symcache_stat_symbol (struct rspamd_symcache *cache,
  148. const gchar *name,
  149. gdouble *frequency,
  150. gdouble *freq_stddev,
  151. gdouble *tm,
  152. guint *nhits);
  153. /**
  154. * Find symbol in cache by its id
  155. * @param cache
  156. * @param id
  157. * @return symbol's name or NULL
  158. */
  159. const gchar *rspamd_symcache_symbol_by_id (struct rspamd_symcache *cache,
  160. gint id);
  161. /**
  162. * Returns number of symbols registered in symbols cache
  163. * @param cache
  164. * @return number of symbols in the cache
  165. */
  166. guint rspamd_symcache_stats_symbols_count (struct rspamd_symcache *cache);
  167. /**
  168. * Call function for cached symbol using saved callback
  169. * @param task task object
  170. * @param cache symbols cache
  171. * @param saved_item pointer to currently saved item
  172. */
  173. gboolean rspamd_symcache_process_symbols (struct rspamd_task *task,
  174. struct rspamd_symcache *cache,
  175. gint stage);
  176. /**
  177. * Validate cache items against theirs weights defined in metrics
  178. * @param cache symbols cache
  179. * @param cfg configuration
  180. * @param strict do strict checks - symbols MUST be described in metrics
  181. */
  182. gboolean rspamd_symcache_validate (struct rspamd_symcache *cache,
  183. struct rspamd_config *cfg,
  184. gboolean strict);
  185. /**
  186. * Return statistics about the cache as ucl object (array of objects one per item)
  187. * @param cache
  188. * @return
  189. */
  190. ucl_object_t *rspamd_symcache_counters (struct rspamd_symcache *cache);
  191. /**
  192. * Start cache reloading
  193. * @param cache
  194. * @param ev_base
  195. */
  196. void rspamd_symcache_start_refresh (struct rspamd_symcache *cache,
  197. struct ev_loop *ev_base,
  198. struct rspamd_worker *w);
  199. /**
  200. * Increases counter for a specific symbol
  201. * @param cache
  202. * @param symbol
  203. */
  204. void rspamd_symcache_inc_frequency (struct rspamd_symcache *cache,
  205. struct rspamd_symcache_item *item);
  206. /**
  207. * Add dependency relation between two symbols identified by id (source) and
  208. * a symbolic name (destination). Destination could be virtual or real symbol.
  209. * Callback destinations are not yet supported.
  210. * @param id_from source symbol
  211. * @param to destination name
  212. */
  213. void rspamd_symcache_add_dependency (struct rspamd_symcache *cache,
  214. gint id_from, const gchar *to,
  215. gint virtual_id_from);
  216. /**
  217. * Add delayed dependency that is resolved on cache post-load routine
  218. * @param cache
  219. * @param from
  220. * @param to
  221. */
  222. void rspamd_symcache_add_delayed_dependency (struct rspamd_symcache *cache,
  223. const gchar *from, const gchar *to);
  224. /**
  225. * Disable specific symbol in the cache
  226. * @param cache
  227. * @param symbol
  228. */
  229. void rspamd_symcache_disable_symbol_perm (struct rspamd_symcache *cache,
  230. const gchar *symbol,
  231. gboolean resolve_parent);
  232. /**
  233. * Enable specific symbol in the cache
  234. * @param cache
  235. * @param symbol
  236. */
  237. void rspamd_symcache_enable_symbol_perm (struct rspamd_symcache *cache,
  238. const gchar *symbol);
  239. /**
  240. * Get abstract callback data for a symbol (or its parent symbol)
  241. * @param cache cache object
  242. * @param symbol symbol name
  243. * @return abstract callback data or NULL if symbol is absent or has no data attached
  244. */
  245. struct rspamd_abstract_callback_data *rspamd_symcache_get_cbdata (
  246. struct rspamd_symcache *cache, const gchar *symbol);
  247. /**
  248. * Returns symbol's parent name (or symbol name itself)
  249. * @param cache
  250. * @param symbol
  251. * @return
  252. */
  253. const gchar *rspamd_symcache_get_parent (struct rspamd_symcache *cache,
  254. const gchar *symbol);
  255. /**
  256. * Adds flags to a symbol
  257. * @param cache
  258. * @param symbol
  259. * @param flags
  260. * @return
  261. */
  262. gboolean rspamd_symcache_add_symbol_flags (struct rspamd_symcache *cache,
  263. const gchar *symbol,
  264. guint flags);
  265. gboolean rspamd_symcache_set_symbol_flags (struct rspamd_symcache *cache,
  266. const gchar *symbol,
  267. guint flags);
  268. guint rspamd_symcache_get_symbol_flags (struct rspamd_symcache *cache,
  269. const gchar *symbol);
  270. void rspamd_symcache_get_symbol_details(struct rspamd_symcache *cache,
  271. const gchar *symbol,
  272. ucl_object_t *this_sym_ucl);
  273. /**
  274. * Process settings for task
  275. * @param task
  276. * @param cache
  277. * @return
  278. */
  279. gboolean rspamd_symcache_process_settings (struct rspamd_task *task,
  280. struct rspamd_symcache *cache);
  281. /**
  282. * Checks if a symbol specified has been checked (or disabled)
  283. * @param task
  284. * @param cache
  285. * @param symbol
  286. * @return
  287. */
  288. gboolean rspamd_symcache_is_checked (struct rspamd_task *task,
  289. struct rspamd_symcache *cache,
  290. const gchar *symbol);
  291. /**
  292. * Returns checksum for all cache items
  293. * @param cache
  294. * @return
  295. */
  296. guint64 rspamd_symcache_get_cksum (struct rspamd_symcache *cache);
  297. /**
  298. * Checks if a symbols is enabled (not checked and conditions return true if present)
  299. * @param task
  300. * @param cache
  301. * @param symbol
  302. * @return
  303. */
  304. gboolean rspamd_symcache_is_symbol_enabled (struct rspamd_task *task,
  305. struct rspamd_symcache *cache,
  306. const gchar *symbol);
  307. /**
  308. * Enable this symbol for task
  309. * @param task
  310. * @param cache
  311. * @param symbol
  312. * @return TRUE if a symbol has been enabled (not executed before)
  313. */
  314. gboolean rspamd_symcache_enable_symbol (struct rspamd_task *task,
  315. struct rspamd_symcache *cache,
  316. const gchar *symbol);
  317. /**
  318. * Enable this symbol for task
  319. * @param task
  320. * @param cache
  321. * @param symbol
  322. * @return TRUE if a symbol has been disabled (not executed before)
  323. */
  324. gboolean rspamd_symcache_disable_symbol (struct rspamd_task *task,
  325. struct rspamd_symcache *cache,
  326. const gchar *symbol);
  327. /**
  328. * Process specific function for each cache element (in order they are added)
  329. * @param cache
  330. * @param func
  331. * @param ud
  332. */
  333. void rspamd_symcache_foreach (struct rspamd_symcache *cache,
  334. void (*func) (struct rspamd_symcache_item *item, gpointer /* userdata */),
  335. gpointer ud);
  336. /**
  337. * Returns the current item being processed (if any)
  338. * @param task
  339. * @return
  340. */
  341. struct rspamd_symcache_item *rspamd_symcache_get_cur_item (struct rspamd_task *task);
  342. /**
  343. * Replaces the current item being processed.
  344. * Returns the current item being processed (if any)
  345. * @param task
  346. * @param item
  347. * @return
  348. */
  349. struct rspamd_symcache_item *rspamd_symcache_set_cur_item (struct rspamd_task *task,
  350. struct rspamd_symcache_item *item);
  351. /**
  352. * Finalize the current async element potentially calling its deps
  353. */
  354. void rspamd_symcache_finalize_item (struct rspamd_task *task,
  355. struct rspamd_symcache_item *item);
  356. /*
  357. * Increase number of async events pending for an item
  358. */
  359. guint rspamd_symcache_item_async_inc_full (struct rspamd_task *task,
  360. struct rspamd_symcache_item *item,
  361. const gchar *subsystem,
  362. const gchar *loc);
  363. #define rspamd_symcache_item_async_inc(task, item, subsystem) \
  364. rspamd_symcache_item_async_inc_full(task, item, subsystem, G_STRLOC)
  365. /*
  366. * Decrease number of async events pending for an item, asserts if no events pending
  367. */
  368. guint rspamd_symcache_item_async_dec_full (struct rspamd_task *task,
  369. struct rspamd_symcache_item *item,
  370. const gchar *subsystem,
  371. const gchar *loc);
  372. #define rspamd_symcache_item_async_dec(task, item, subsystem) \
  373. rspamd_symcache_item_async_dec_full(task, item, subsystem, G_STRLOC)
  374. /**
  375. * Decrease number of async events pending for an item, asserts if no events pending
  376. * If no events are left, this function calls `rspamd_symbols_cache_finalize_item` and returns TRUE
  377. * @param task
  378. * @param item
  379. * @return
  380. */
  381. gboolean rspamd_symcache_item_async_dec_check_full (struct rspamd_task *task,
  382. struct rspamd_symcache_item *item,
  383. const gchar *subsystem,
  384. const gchar *loc);
  385. #define rspamd_symcache_item_async_dec_check(task, item, subsystem) \
  386. rspamd_symcache_item_async_dec_check_full(task, item, subsystem, G_STRLOC)
  387. /**
  388. * Disables execution of all symbols, excluding those specified in `skip_mask`
  389. * @param task
  390. * @param cache
  391. * @param skip_mask
  392. */
  393. void rspamd_symcache_disable_all_symbols (struct rspamd_task *task,
  394. struct rspamd_symcache *cache,
  395. guint skip_mask);
  396. /**
  397. * Iterates over the list of the enabled composites calling specified function
  398. * @param task
  399. * @param cache
  400. * @param func
  401. * @param fd
  402. */
  403. void rspamd_symcache_composites_foreach (struct rspamd_task *task,
  404. struct rspamd_symcache *cache,
  405. GHFunc func,
  406. gpointer fd);
  407. /**
  408. * Sets allowed settings ids for a symbol
  409. * @param cache
  410. * @param symbol
  411. * @param ids
  412. * @param nids
  413. */
  414. bool rspamd_symcache_set_allowed_settings_ids (struct rspamd_symcache *cache,
  415. const gchar *symbol,
  416. const guint32 *ids,
  417. guint nids);
  418. /**
  419. * Sets denied settings ids for a symbol
  420. * @param cache
  421. * @param symbol
  422. * @param ids
  423. * @param nids
  424. */
  425. bool rspamd_symcache_set_forbidden_settings_ids (struct rspamd_symcache *cache,
  426. const gchar *symbol,
  427. const guint32 *ids,
  428. guint nids);
  429. /**
  430. * Returns allowed ids for a symbol as a constant array
  431. * @param cache
  432. * @param symbol
  433. * @param nids
  434. * @return
  435. */
  436. const guint32 *rspamd_symcache_get_allowed_settings_ids (struct rspamd_symcache *cache,
  437. const gchar *symbol,
  438. guint *nids);
  439. /**
  440. * Returns denied ids for a symbol as a constant array
  441. * @param cache
  442. * @param symbol
  443. * @param nids
  444. * @return
  445. */
  446. const guint32 *rspamd_symcache_get_forbidden_settings_ids (struct rspamd_symcache *cache,
  447. const gchar *symbol,
  448. guint *nids);
  449. /**
  450. * Processes settings_elt in cache and converts it to a set of
  451. * adjustments for forbidden/allowed settings_ids for each symbol
  452. * @param cache
  453. * @param elt
  454. */
  455. void rspamd_symcache_process_settings_elt (struct rspamd_symcache *cache,
  456. struct rspamd_config_settings_elt *elt);
  457. /**
  458. * Check if a symbol is allowed for execution/insertion, this does not involve
  459. * condition scripts to be checked (so it is intended to be fast).
  460. * @param task
  461. * @param item
  462. * @param exec_only
  463. * @return
  464. */
  465. gboolean rspamd_symcache_is_item_allowed (struct rspamd_task *task,
  466. struct rspamd_symcache_item *item,
  467. gboolean exec_only);
  468. /**
  469. * Returns symcache item flags
  470. * @param item
  471. * @return
  472. */
  473. gint rspamd_symcache_item_flags (struct rspamd_symcache_item *item);
  474. /**
  475. * Returns cache item name
  476. * @param item
  477. * @return
  478. */
  479. const gchar* rspamd_symcache_item_name (struct rspamd_symcache_item *item);
  480. /**
  481. * Returns the current item stat
  482. * @param item
  483. * @return
  484. */
  485. const struct rspamd_symcache_item_stat *
  486. rspamd_symcache_item_stat (struct rspamd_symcache_item *item);
  487. /**
  488. * Returns if an item is enabled (for virtual it also means that parent should be enabled)
  489. * @param item
  490. * @return
  491. */
  492. gboolean rspamd_symcache_item_is_enabled (struct rspamd_symcache_item *item);
  493. /**
  494. * Returns parent for virtual symbols (or NULL)
  495. * @param item
  496. * @return
  497. */
  498. struct rspamd_symcache_item * rspamd_symcache_item_get_parent (
  499. struct rspamd_symcache_item *item);
  500. /**
  501. * Returns direct deps for an element
  502. * @param item
  503. * @return array of struct rspamd_symcache_item *
  504. */
  505. const GPtrArray* rspamd_symcache_item_get_deps (
  506. struct rspamd_symcache_item *item);
  507. /**
  508. * Returns direct reverse deps for an element
  509. * @param item
  510. * @return array of struct rspamd_symcache_item *
  511. */
  512. const GPtrArray* rspamd_symcache_item_get_rdeps (
  513. struct rspamd_symcache_item *item);
  514. /**
  515. * Enable profiling for task (e.g. when a slow rule has been found)
  516. * @param task
  517. */
  518. void rspamd_symcache_enable_profile (struct rspamd_task *task);
  519. #ifdef __cplusplus
  520. }
  521. #endif
  522. #endif