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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  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. /**
  271. * Process settings for task
  272. * @param task
  273. * @param cache
  274. * @return
  275. */
  276. gboolean rspamd_symcache_process_settings (struct rspamd_task *task,
  277. struct rspamd_symcache *cache);
  278. /**
  279. * Checks if a symbol specified has been checked (or disabled)
  280. * @param task
  281. * @param cache
  282. * @param symbol
  283. * @return
  284. */
  285. gboolean rspamd_symcache_is_checked (struct rspamd_task *task,
  286. struct rspamd_symcache *cache,
  287. const gchar *symbol);
  288. /**
  289. * Returns checksum for all cache items
  290. * @param cache
  291. * @return
  292. */
  293. guint64 rspamd_symcache_get_cksum (struct rspamd_symcache *cache);
  294. /**
  295. * Checks if a symbols is enabled (not checked and conditions return true if present)
  296. * @param task
  297. * @param cache
  298. * @param symbol
  299. * @return
  300. */
  301. gboolean rspamd_symcache_is_symbol_enabled (struct rspamd_task *task,
  302. struct rspamd_symcache *cache,
  303. const gchar *symbol);
  304. /**
  305. * Enable this symbol for task
  306. * @param task
  307. * @param cache
  308. * @param symbol
  309. * @return TRUE if a symbol has been enabled (not executed before)
  310. */
  311. gboolean rspamd_symcache_enable_symbol (struct rspamd_task *task,
  312. struct rspamd_symcache *cache,
  313. const gchar *symbol);
  314. /**
  315. * Enable this symbol for task
  316. * @param task
  317. * @param cache
  318. * @param symbol
  319. * @return TRUE if a symbol has been disabled (not executed before)
  320. */
  321. gboolean rspamd_symcache_disable_symbol (struct rspamd_task *task,
  322. struct rspamd_symcache *cache,
  323. const gchar *symbol);
  324. /**
  325. * Process specific function for each cache element (in order they are added)
  326. * @param cache
  327. * @param func
  328. * @param ud
  329. */
  330. void rspamd_symcache_foreach (struct rspamd_symcache *cache,
  331. void (*func) (struct rspamd_symcache_item *item, gpointer /* userdata */),
  332. gpointer ud);
  333. /**
  334. * Returns the current item being processed (if any)
  335. * @param task
  336. * @return
  337. */
  338. struct rspamd_symcache_item *rspamd_symcache_get_cur_item (struct rspamd_task *task);
  339. /**
  340. * Replaces the current item being processed.
  341. * Returns the current item being processed (if any)
  342. * @param task
  343. * @param item
  344. * @return
  345. */
  346. struct rspamd_symcache_item *rspamd_symcache_set_cur_item (struct rspamd_task *task,
  347. struct rspamd_symcache_item *item);
  348. /**
  349. * Finalize the current async element potentially calling its deps
  350. */
  351. void rspamd_symcache_finalize_item (struct rspamd_task *task,
  352. struct rspamd_symcache_item *item);
  353. /*
  354. * Increase number of async events pending for an item
  355. */
  356. guint rspamd_symcache_item_async_inc_full (struct rspamd_task *task,
  357. struct rspamd_symcache_item *item,
  358. const gchar *subsystem,
  359. const gchar *loc);
  360. #define rspamd_symcache_item_async_inc(task, item, subsystem) \
  361. rspamd_symcache_item_async_inc_full(task, item, subsystem, G_STRLOC)
  362. /*
  363. * Decrease number of async events pending for an item, asserts if no events pending
  364. */
  365. guint rspamd_symcache_item_async_dec_full (struct rspamd_task *task,
  366. struct rspamd_symcache_item *item,
  367. const gchar *subsystem,
  368. const gchar *loc);
  369. #define rspamd_symcache_item_async_dec(task, item, subsystem) \
  370. rspamd_symcache_item_async_dec_full(task, item, subsystem, G_STRLOC)
  371. /**
  372. * Decrease number of async events pending for an item, asserts if no events pending
  373. * If no events are left, this function calls `rspamd_symbols_cache_finalize_item` and returns TRUE
  374. * @param task
  375. * @param item
  376. * @return
  377. */
  378. gboolean rspamd_symcache_item_async_dec_check_full (struct rspamd_task *task,
  379. struct rspamd_symcache_item *item,
  380. const gchar *subsystem,
  381. const gchar *loc);
  382. #define rspamd_symcache_item_async_dec_check(task, item, subsystem) \
  383. rspamd_symcache_item_async_dec_check_full(task, item, subsystem, G_STRLOC)
  384. /**
  385. * Disables execution of all symbols, excluding those specified in `skip_mask`
  386. * @param task
  387. * @param cache
  388. * @param skip_mask
  389. */
  390. void rspamd_symcache_disable_all_symbols (struct rspamd_task *task,
  391. struct rspamd_symcache *cache,
  392. guint skip_mask);
  393. /**
  394. * Iterates over the list of the enabled composites calling specified function
  395. * @param task
  396. * @param cache
  397. * @param func
  398. * @param fd
  399. */
  400. void rspamd_symcache_composites_foreach (struct rspamd_task *task,
  401. struct rspamd_symcache *cache,
  402. GHFunc func,
  403. gpointer fd);
  404. /**
  405. * Sets allowed settings ids for a symbol
  406. * @param cache
  407. * @param symbol
  408. * @param ids
  409. * @param nids
  410. */
  411. bool rspamd_symcache_set_allowed_settings_ids (struct rspamd_symcache *cache,
  412. const gchar *symbol,
  413. const guint32 *ids,
  414. guint nids);
  415. /**
  416. * Sets denied settings ids for a symbol
  417. * @param cache
  418. * @param symbol
  419. * @param ids
  420. * @param nids
  421. */
  422. bool rspamd_symcache_set_forbidden_settings_ids (struct rspamd_symcache *cache,
  423. const gchar *symbol,
  424. const guint32 *ids,
  425. guint nids);
  426. /**
  427. * Returns allowed ids for a symbol as a constant array
  428. * @param cache
  429. * @param symbol
  430. * @param nids
  431. * @return
  432. */
  433. const guint32 *rspamd_symcache_get_allowed_settings_ids (struct rspamd_symcache *cache,
  434. const gchar *symbol,
  435. guint *nids);
  436. /**
  437. * Returns denied ids for a symbol as a constant array
  438. * @param cache
  439. * @param symbol
  440. * @param nids
  441. * @return
  442. */
  443. const guint32 *rspamd_symcache_get_forbidden_settings_ids (struct rspamd_symcache *cache,
  444. const gchar *symbol,
  445. guint *nids);
  446. /**
  447. * Processes settings_elt in cache and converts it to a set of
  448. * adjustments for forbidden/allowed settings_ids for each symbol
  449. * @param cache
  450. * @param elt
  451. */
  452. void rspamd_symcache_process_settings_elt (struct rspamd_symcache *cache,
  453. struct rspamd_config_settings_elt *elt);
  454. /**
  455. * Check if a symbol is allowed for execution/insertion, this does not involve
  456. * condition scripts to be checked (so it is intended to be fast).
  457. * @param task
  458. * @param item
  459. * @param exec_only
  460. * @return
  461. */
  462. gboolean rspamd_symcache_is_item_allowed (struct rspamd_task *task,
  463. struct rspamd_symcache_item *item,
  464. gboolean exec_only);
  465. /**
  466. * Returns symbcache item flags
  467. * @param item
  468. * @return
  469. */
  470. gint rspamd_symcache_item_flags (struct rspamd_symcache_item *item);
  471. /**
  472. * Returns cache item name
  473. * @param item
  474. * @return
  475. */
  476. const gchar* rspamd_symcache_item_name (struct rspamd_symcache_item *item);
  477. /**
  478. * Returns the current item stat
  479. * @param item
  480. * @return
  481. */
  482. const struct rspamd_symcache_item_stat *
  483. rspamd_symcache_item_stat (struct rspamd_symcache_item *item);
  484. /**
  485. * Returns if an item is enabled (for virutal it also means that parent should be enabled)
  486. * @param item
  487. * @return
  488. */
  489. gboolean rspamd_symcache_item_is_enabled (struct rspamd_symcache_item *item);
  490. /**
  491. * Returns parent for virtual symbols (or NULL)
  492. * @param item
  493. * @return
  494. */
  495. struct rspamd_symcache_item * rspamd_symcache_item_get_parent (
  496. struct rspamd_symcache_item *item);
  497. /**
  498. * Returns direct deps for an element
  499. * @param item
  500. * @return array of struct rspamd_symcache_item *
  501. */
  502. const GPtrArray* rspamd_symcache_item_get_deps (
  503. struct rspamd_symcache_item *item);
  504. /**
  505. * Returns direct reverse deps for an element
  506. * @param item
  507. * @return array of struct rspamd_symcache_item *
  508. */
  509. const GPtrArray* rspamd_symcache_item_get_rdeps (
  510. struct rspamd_symcache_item *item);
  511. /**
  512. * Enable profiling for task (e.g. when a slow rule has been found)
  513. * @param task
  514. */
  515. void rspamd_symcache_enable_profile (struct rspamd_task *task);
  516. #ifdef __cplusplus
  517. }
  518. #endif
  519. #endif