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.

upstream.h 8.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  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 UPSTREAM_H
  17. #define UPSTREAM_H
  18. #include "config.h"
  19. #include "util.h"
  20. #include "rdns.h"
  21. #include "ucl.h"
  22. #ifdef __cplusplus
  23. extern "C" {
  24. #endif
  25. /* Forward declaration */
  26. struct ev_loop;
  27. enum rspamd_upstream_rotation {
  28. RSPAMD_UPSTREAM_RANDOM = 0,
  29. RSPAMD_UPSTREAM_HASHED,
  30. RSPAMD_UPSTREAM_ROUND_ROBIN,
  31. RSPAMD_UPSTREAM_MASTER_SLAVE,
  32. RSPAMD_UPSTREAM_SEQUENTIAL,
  33. RSPAMD_UPSTREAM_UNDEF
  34. };
  35. enum rspamd_upstream_flag {
  36. RSPAMD_UPSTREAM_FLAG_NORESOLVE = (1 << 0),
  37. RSPAMD_UPSTREAM_FLAG_SRV_RESOLVE = (1 << 1),
  38. };
  39. struct rspamd_config;
  40. /* Opaque upstream structures */
  41. struct upstream;
  42. struct upstream_list;
  43. struct upstream_ctx;
  44. /**
  45. * Init upstreams library
  46. * @param resolver
  47. */
  48. struct upstream_ctx *rspamd_upstreams_library_init(void);
  49. /**
  50. * Remove reference from upstreams library
  51. */
  52. void rspamd_upstreams_library_unref(struct upstream_ctx *ctx);
  53. /**
  54. * Configure attributes of upstreams library
  55. * @param cfg
  56. */
  57. void rspamd_upstreams_library_config(struct rspamd_config *cfg,
  58. struct upstream_ctx *ctx, struct ev_loop *event_loop,
  59. struct rdns_resolver *resolver);
  60. /**
  61. * Upstream error logic
  62. * 1. During error time we count upstream_ok and upstream_fail
  63. * 2. If failcount is more then maxerrors then we mark upstream as unavailable for dead time
  64. * 3. After dead time we mark upstream as alive and go to the step 1
  65. * 4. If all upstreams are dead, marks every upstream as alive
  66. */
  67. /**
  68. * Add an error to an upstream
  69. */
  70. void rspamd_upstream_fail(struct upstream *upstream, gboolean addr_failure, const char *reason);
  71. /**
  72. * Increase upstream successes count
  73. */
  74. void rspamd_upstream_ok(struct upstream *up);
  75. /**
  76. * Set weight for an upstream
  77. * @param up
  78. */
  79. void rspamd_upstream_set_weight(struct upstream *up, unsigned int weight);
  80. /**
  81. * Create new list of upstreams
  82. * @return
  83. */
  84. struct upstream_list *rspamd_upstreams_create(struct upstream_ctx *ctx);
  85. /**
  86. * Sets specific flag to the upstream list
  87. * @param ups
  88. * @param flags
  89. */
  90. void rspamd_upstreams_set_flags(struct upstream_list *ups,
  91. enum rspamd_upstream_flag flags);
  92. /**
  93. * Sets custom limits for upstreams
  94. * This function allocates memory from the upstreams ctx pool and should
  95. * not be called in cycles/constantly as this memory is likely persistent
  96. * @param ups
  97. * @param revive_time
  98. * @param revive_jitter
  99. * @param error_time
  100. * @param dns_timeout
  101. * @param max_errors
  102. * @param dns_retransmits
  103. */
  104. void rspamd_upstreams_set_limits(struct upstream_list *ups,
  105. double revive_time,
  106. double revive_jitter,
  107. double error_time,
  108. double dns_timeout,
  109. unsigned int max_errors,
  110. unsigned int dns_retransmits);
  111. /**
  112. * Sets rotation policy for upstreams list
  113. * @param ups
  114. * @param rot
  115. */
  116. void rspamd_upstreams_set_rotation(struct upstream_list *ups,
  117. enum rspamd_upstream_rotation rot);
  118. /**
  119. * Destroy list of upstreams
  120. * @param ups
  121. */
  122. void rspamd_upstreams_destroy(struct upstream_list *ups);
  123. /**
  124. * Returns count of upstreams in a list
  125. * @param ups
  126. * @return
  127. */
  128. gsize rspamd_upstreams_count(struct upstream_list *ups);
  129. /**
  130. * Returns the number of upstreams in the list
  131. * @param ups
  132. * @return
  133. */
  134. gsize rspamd_upstreams_alive(struct upstream_list *ups);
  135. enum rspamd_upstream_parse_type {
  136. RSPAMD_UPSTREAM_PARSE_DEFAULT = 0,
  137. RSPAMD_UPSTREAM_PARSE_NAMESERVER,
  138. };
  139. /**
  140. * Add upstream from the string
  141. * @param ups upstream list
  142. * @param str string in format "name[:port[:priority]]"
  143. * @param def_port default port number
  144. * @param data optional userdata
  145. * @return TRUE if upstream has been added
  146. */
  147. gboolean rspamd_upstreams_add_upstream(struct upstream_list *ups, const char *str,
  148. uint16_t def_port, enum rspamd_upstream_parse_type parse_type,
  149. void *data);
  150. /**
  151. * Add multiple upstreams from comma, semicolon or space separated line
  152. * @param ups upstream list
  153. * @param str string in format "(<ups>([<sep>+]<ups>)*)+"
  154. * @param def_port default port number
  155. * @param data optional userdata
  156. * @return TRUE if **any** of upstreams has been added
  157. */
  158. gboolean rspamd_upstreams_parse_line(struct upstream_list *ups,
  159. const char *str, uint16_t def_port, void *data);
  160. gboolean rspamd_upstreams_parse_line_len(struct upstream_list *ups,
  161. const char *str, gsize len,
  162. uint16_t def_port,
  163. void *data);
  164. /**
  165. * Parse upstreams list from the UCL object
  166. * @param ups
  167. * @param in
  168. * @param def_port
  169. * @param data
  170. * @return
  171. */
  172. gboolean rspamd_upstreams_from_ucl(struct upstream_list *ups,
  173. const ucl_object_t *in, uint16_t def_port, void *data);
  174. typedef void (*rspamd_upstream_traverse_func)(struct upstream *up, unsigned int idx,
  175. void *ud);
  176. /**
  177. * Traverse upstreams list calling the function specified
  178. * @param ups
  179. * @param cb
  180. * @param ud
  181. */
  182. void rspamd_upstreams_foreach(struct upstream_list *ups,
  183. rspamd_upstream_traverse_func cb, void *ud);
  184. enum rspamd_upstreams_watch_event {
  185. RSPAMD_UPSTREAM_WATCH_SUCCESS = 1u << 0,
  186. RSPAMD_UPSTREAM_WATCH_FAILURE = 1u << 1,
  187. RSPAMD_UPSTREAM_WATCH_OFFLINE = 1u << 2,
  188. RSPAMD_UPSTREAM_WATCH_ONLINE = 1u << 3,
  189. RSPAMD_UPSTREAM_WATCH_ALL = (1u << 0) | (1u << 1) | (1u << 2) | (1u << 3),
  190. };
  191. typedef void (*rspamd_upstream_watch_func)(struct upstream *up,
  192. enum rspamd_upstreams_watch_event event,
  193. unsigned int cur_errors,
  194. void *ud);
  195. /**
  196. * Adds new watcher to the upstreams list
  197. * @param ups
  198. * @param events
  199. * @param func
  200. * @param ud
  201. */
  202. void rspamd_upstreams_add_watch_callback(struct upstream_list *ups,
  203. enum rspamd_upstreams_watch_event events,
  204. rspamd_upstream_watch_func func,
  205. GFreeFunc free_func,
  206. gpointer ud);
  207. /**
  208. * Returns the next IP address of the upstream (internal rotation)
  209. * @param up
  210. * @return
  211. */
  212. rspamd_inet_addr_t *rspamd_upstream_addr_next(struct upstream *up);
  213. /**
  214. * Returns the current IP address of the upstream
  215. * @param up
  216. * @return
  217. */
  218. rspamd_inet_addr_t *rspamd_upstream_addr_cur(const struct upstream *up);
  219. /**
  220. * Add custom address for an upstream (ownership of addr is transferred to upstream)
  221. * @param up
  222. * @return
  223. */
  224. gboolean rspamd_upstream_add_addr(struct upstream *up,
  225. rspamd_inet_addr_t *addr);
  226. /**
  227. * Returns the symbolic name of the upstream
  228. * @param up
  229. * @return
  230. */
  231. const char *rspamd_upstream_name(struct upstream *up);
  232. /**
  233. * Returns the port of the current address for the upstream
  234. * @param up
  235. * @return
  236. */
  237. int rspamd_upstream_port(struct upstream *up);
  238. /**
  239. * Sets opaque user data associated with this upstream
  240. * @param up
  241. * @param data
  242. * @return old data
  243. */
  244. gpointer rspamd_upstream_set_data(struct upstream *up, gpointer data);
  245. /**
  246. * Gets opaque user data associated with this upstream
  247. * @param up
  248. * @return
  249. */
  250. gpointer rspamd_upstream_get_data(struct upstream *up);
  251. /**
  252. * Get new upstream from the list
  253. * @param ups upstream list
  254. * @param type type of rotation algorithm, for `RSPAMD_UPSTREAM_HASHED` it is required to specify `key` and `keylen` as arguments
  255. * @return
  256. */
  257. struct upstream *rspamd_upstream_get(struct upstream_list *ups,
  258. enum rspamd_upstream_rotation default_type,
  259. const unsigned char *key, gsize keylen);
  260. /**
  261. * Get new upstream from the list
  262. * @param ups upstream list
  263. * @param type type of rotation algorithm, for `RSPAMD_UPSTREAM_HASHED` it is required to specify `key` and `keylen` as arguments
  264. * @return
  265. */
  266. struct upstream *rspamd_upstream_get_forced(struct upstream_list *ups,
  267. enum rspamd_upstream_rotation forced_type,
  268. const unsigned char *key, gsize keylen);
  269. /**
  270. * Get new upstream from the list excepting the upstream specified
  271. * @param ups upstream list
  272. * @param type type of rotation algorithm, for `RSPAMD_UPSTREAM_HASHED` it is required to specify `key` and `keylen` as arguments
  273. * @return
  274. */
  275. struct upstream *rspamd_upstream_get_except(struct upstream_list *ups,
  276. struct upstream *except,
  277. enum rspamd_upstream_rotation default_type,
  278. const unsigned char *key, gsize keylen);
  279. /**
  280. * Re-resolve addresses for all upstreams registered
  281. */
  282. void rspamd_upstream_reresolve(struct upstream_ctx *ctx);
  283. /**
  284. * Share ownership on upstream
  285. * @param up
  286. * @return
  287. */
  288. struct upstream *rspamd_upstream_ref(struct upstream *up);
  289. /**
  290. * Unshare ownership on upstream
  291. * @param up
  292. */
  293. void rspamd_upstream_unref(struct upstream *up);
  294. #ifdef __cplusplus
  295. }
  296. #endif
  297. #endif /* UPSTREAM_H */