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

16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
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 */