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.c 43KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761
  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. #include "config.h"
  17. #include "upstream.h"
  18. #include "ottery.h"
  19. #include "ref.h"
  20. #include "cfg_file.h"
  21. #include "rdns.h"
  22. #include "cryptobox.h"
  23. #include "utlist.h"
  24. #include "logger.h"
  25. #include "contrib/librdns/rdns.h"
  26. #include "contrib/mumhash/mum.h"
  27. #include <math.h>
  28. struct upstream_inet_addr_entry {
  29. rspamd_inet_addr_t *addr;
  30. guint priority;
  31. struct upstream_inet_addr_entry *next;
  32. };
  33. struct upstream_addr_elt {
  34. rspamd_inet_addr_t *addr;
  35. guint priority;
  36. guint errors;
  37. };
  38. struct upstream_list_watcher {
  39. rspamd_upstream_watch_func func;
  40. GFreeFunc dtor;
  41. gpointer ud;
  42. enum rspamd_upstreams_watch_event events_mask;
  43. struct upstream_list_watcher *next, *prev;
  44. };
  45. struct upstream {
  46. guint weight;
  47. guint cur_weight;
  48. guint errors;
  49. guint checked;
  50. guint dns_requests;
  51. gint active_idx;
  52. guint ttl;
  53. gchar *name;
  54. ev_timer ev;
  55. gdouble last_fail;
  56. gdouble last_resolve;
  57. gpointer ud;
  58. enum rspamd_upstream_flag flags;
  59. struct upstream_list *ls;
  60. GList *ctx_pos;
  61. struct upstream_ctx *ctx;
  62. struct {
  63. GPtrArray *addr; /* struct upstream_addr_elt */
  64. guint cur;
  65. } addrs;
  66. struct upstream_inet_addr_entry *new_addrs;
  67. gpointer data;
  68. gchar uid[8];
  69. ref_entry_t ref;
  70. #ifdef UPSTREAMS_THREAD_SAFE
  71. rspamd_mutex_t *lock;
  72. #endif
  73. };
  74. struct upstream_limits {
  75. gdouble revive_time;
  76. gdouble revive_jitter;
  77. gdouble error_time;
  78. gdouble dns_timeout;
  79. gdouble lazy_resolve_time;
  80. guint max_errors;
  81. guint dns_retransmits;
  82. };
  83. struct upstream_list {
  84. gchar *ups_line;
  85. struct upstream_ctx *ctx;
  86. GPtrArray *ups;
  87. GPtrArray *alive;
  88. struct upstream_list_watcher *watchers;
  89. guint64 hash_seed;
  90. const struct upstream_limits *limits;
  91. enum rspamd_upstream_flag flags;
  92. guint cur_elt;
  93. enum rspamd_upstream_rotation rot_alg;
  94. #ifdef UPSTREAMS_THREAD_SAFE
  95. rspamd_mutex_t *lock;
  96. #endif
  97. };
  98. struct upstream_ctx {
  99. struct rdns_resolver *res;
  100. struct ev_loop *event_loop;
  101. struct upstream_limits limits;
  102. GQueue *upstreams;
  103. gboolean configured;
  104. rspamd_mempool_t *pool;
  105. ref_entry_t ref;
  106. };
  107. #ifndef UPSTREAMS_THREAD_SAFE
  108. #define RSPAMD_UPSTREAM_LOCK(x) do { } while (0)
  109. #define RSPAMD_UPSTREAM_UNLOCK(x) do { } while (0)
  110. #else
  111. #define RSPAMD_UPSTREAM_LOCK(x) rspamd_mutex_lock(x->lock)
  112. #define RSPAMD_UPSTREAM_UNLOCK(x) rspamd_mutex_unlock(x->lock)
  113. #endif
  114. #define msg_debug_upstream(...) rspamd_conditional_debug_fast (NULL, NULL, \
  115. rspamd_upstream_log_id, "upstream", upstream->uid, \
  116. G_STRFUNC, \
  117. __VA_ARGS__)
  118. #define msg_info_upstream(...) rspamd_default_log_function (G_LOG_LEVEL_INFO, \
  119. "upstream", upstream->uid, \
  120. G_STRFUNC, \
  121. __VA_ARGS__)
  122. #define msg_err_upstream(...) rspamd_default_log_function (G_LOG_LEVEL_INFO, \
  123. "upstream", upstream->uid, \
  124. G_STRFUNC, \
  125. __VA_ARGS__)
  126. INIT_LOG_MODULE(upstream)
  127. /* 4 errors in 10 seconds */
  128. #define DEFAULT_MAX_ERRORS 4
  129. static const guint default_max_errors = DEFAULT_MAX_ERRORS;
  130. #define DEFAULT_REVIVE_TIME 60
  131. static const gdouble default_revive_time = DEFAULT_REVIVE_TIME;
  132. #define DEFAULT_REVIVE_JITTER 0.4
  133. static const gdouble default_revive_jitter = DEFAULT_REVIVE_JITTER;
  134. #define DEFAULT_ERROR_TIME 10
  135. static const gdouble default_error_time = DEFAULT_ERROR_TIME;
  136. #define DEFAULT_DNS_TIMEOUT 1.0
  137. static const gdouble default_dns_timeout = DEFAULT_DNS_TIMEOUT;
  138. #define DEFAULT_DNS_RETRANSMITS 2
  139. static const guint default_dns_retransmits = DEFAULT_DNS_RETRANSMITS;
  140. /* TODO: make it configurable */
  141. #define DEFAULT_LAZY_RESOLVE_TIME 3600.0
  142. static const gdouble default_lazy_resolve_time = DEFAULT_LAZY_RESOLVE_TIME;
  143. static const struct upstream_limits default_limits = {
  144. .revive_time = DEFAULT_REVIVE_TIME,
  145. .revive_jitter = DEFAULT_REVIVE_JITTER,
  146. .error_time = DEFAULT_ERROR_TIME,
  147. .dns_timeout = DEFAULT_DNS_TIMEOUT,
  148. .dns_retransmits = DEFAULT_DNS_RETRANSMITS,
  149. .max_errors = DEFAULT_MAX_ERRORS,
  150. .lazy_resolve_time = DEFAULT_LAZY_RESOLVE_TIME,
  151. };
  152. static void rspamd_upstream_lazy_resolve_cb (struct ev_loop *, ev_timer *, int );
  153. void
  154. rspamd_upstreams_library_config (struct rspamd_config *cfg,
  155. struct upstream_ctx *ctx,
  156. struct ev_loop *event_loop,
  157. struct rdns_resolver *resolver)
  158. {
  159. g_assert (ctx != NULL);
  160. g_assert (cfg != NULL);
  161. if (cfg->upstream_error_time) {
  162. ctx->limits.error_time = cfg->upstream_error_time;
  163. }
  164. if (cfg->upstream_max_errors) {
  165. ctx->limits.max_errors = cfg->upstream_max_errors;
  166. }
  167. if (cfg->upstream_revive_time) {
  168. ctx->limits.revive_time = cfg->upstream_max_errors;
  169. }
  170. if (cfg->upstream_lazy_resolve_time) {
  171. ctx->limits.lazy_resolve_time = cfg->upstream_lazy_resolve_time;
  172. }
  173. if (cfg->dns_retransmits) {
  174. ctx->limits.dns_retransmits = cfg->dns_retransmits;
  175. }
  176. if (cfg->dns_timeout) {
  177. ctx->limits.dns_timeout = cfg->dns_timeout;
  178. }
  179. ctx->event_loop = event_loop;
  180. ctx->res = resolver;
  181. ctx->configured = TRUE;
  182. /* Start lazy resolving */
  183. if (event_loop && resolver) {
  184. GList *cur;
  185. struct upstream *upstream;
  186. cur = ctx->upstreams->head;
  187. while (cur) {
  188. upstream = cur->data;
  189. if (!ev_can_stop (&upstream->ev) && upstream->ls &&
  190. !(upstream->flags & RSPAMD_UPSTREAM_FLAG_NORESOLVE)) {
  191. gdouble when;
  192. if (upstream->flags & RSPAMD_UPSTREAM_FLAG_SRV_RESOLVE) {
  193. /* Resolve them immediately ! */
  194. when = 0.0;
  195. }
  196. else {
  197. when = rspamd_time_jitter (upstream->ls->limits->lazy_resolve_time,
  198. upstream->ls->limits->lazy_resolve_time * .1);
  199. }
  200. ev_timer_init (&upstream->ev, rspamd_upstream_lazy_resolve_cb,
  201. when, 0);
  202. upstream->ev.data = upstream;
  203. ev_timer_start (ctx->event_loop, &upstream->ev);
  204. }
  205. cur = g_list_next (cur);
  206. }
  207. }
  208. }
  209. static void
  210. rspamd_upstream_ctx_dtor (struct upstream_ctx *ctx)
  211. {
  212. GList *cur;
  213. struct upstream *u;
  214. cur = ctx->upstreams->head;
  215. while (cur) {
  216. u = cur->data;
  217. u->ctx = NULL;
  218. u->ctx_pos = NULL;
  219. cur = g_list_next (cur);
  220. }
  221. g_queue_free (ctx->upstreams);
  222. rspamd_mempool_delete (ctx->pool);
  223. g_free (ctx);
  224. }
  225. void
  226. rspamd_upstreams_library_unref (struct upstream_ctx *ctx)
  227. {
  228. REF_RELEASE (ctx);
  229. }
  230. struct upstream_ctx *
  231. rspamd_upstreams_library_init (void)
  232. {
  233. struct upstream_ctx *ctx;
  234. ctx = g_malloc0 (sizeof (*ctx));
  235. memcpy (&ctx->limits, &default_limits, sizeof (ctx->limits));
  236. ctx->pool = rspamd_mempool_new (rspamd_mempool_suggest_size (),
  237. "upstreams", 0);
  238. ctx->upstreams = g_queue_new ();
  239. REF_INIT_RETAIN (ctx, rspamd_upstream_ctx_dtor);
  240. return ctx;
  241. }
  242. static gint
  243. rspamd_upstream_af_to_weight (const rspamd_inet_addr_t *addr)
  244. {
  245. int ret;
  246. switch (rspamd_inet_address_get_af (addr)) {
  247. case AF_UNIX:
  248. ret = 2;
  249. break;
  250. case AF_INET:
  251. ret = 1;
  252. break;
  253. default:
  254. ret = 0;
  255. break;
  256. }
  257. return ret;
  258. }
  259. /*
  260. * Select IPv4 addresses before IPv6
  261. */
  262. static gint
  263. rspamd_upstream_addr_sort_func (gconstpointer a, gconstpointer b)
  264. {
  265. const struct upstream_addr_elt *ip1 = *(const struct upstream_addr_elt **)a,
  266. *ip2 = *(const struct upstream_addr_elt **)b;
  267. gint w1, w2;
  268. if (ip1->priority == 0 && ip2->priority == 0) {
  269. w1 = rspamd_upstream_af_to_weight (ip1->addr);
  270. w2 = rspamd_upstream_af_to_weight (ip2->addr);
  271. }
  272. else {
  273. w1 = ip1->priority;
  274. w2 = ip2->priority;
  275. }
  276. /* Inverse order */
  277. return w2 - w1;
  278. }
  279. static void
  280. rspamd_upstream_set_active (struct upstream_list *ls, struct upstream *upstream)
  281. {
  282. RSPAMD_UPSTREAM_LOCK (ls);
  283. g_ptr_array_add (ls->alive, upstream);
  284. upstream->active_idx = ls->alive->len - 1;
  285. if (upstream->ctx && upstream->ctx->configured &&
  286. !(upstream->flags & RSPAMD_UPSTREAM_FLAG_NORESOLVE)) {
  287. if (ev_can_stop (&upstream->ev)) {
  288. ev_timer_stop (upstream->ctx->event_loop, &upstream->ev);
  289. }
  290. /* Start lazy (or not so lazy) names resolution */
  291. gdouble when;
  292. if (upstream->flags & RSPAMD_UPSTREAM_FLAG_SRV_RESOLVE) {
  293. /* Resolve them immediately ! */
  294. when = 0.0;
  295. }
  296. else {
  297. when = rspamd_time_jitter (upstream->ls->limits->lazy_resolve_time,
  298. upstream->ls->limits->lazy_resolve_time * .1);
  299. }
  300. ev_timer_init (&upstream->ev, rspamd_upstream_lazy_resolve_cb,
  301. when, 0);
  302. upstream->ev.data = upstream;
  303. msg_debug_upstream ("start lazy resolving for %s in %.0f seconds",
  304. upstream->name, when);
  305. ev_timer_start (upstream->ctx->event_loop, &upstream->ev);
  306. }
  307. RSPAMD_UPSTREAM_UNLOCK (ls);
  308. }
  309. static void
  310. rspamd_upstream_addr_elt_dtor (gpointer a)
  311. {
  312. struct upstream_addr_elt *elt = a;
  313. if (elt) {
  314. rspamd_inet_address_free (elt->addr);
  315. g_free (elt);
  316. }
  317. }
  318. static void
  319. rspamd_upstream_update_addrs (struct upstream *upstream)
  320. {
  321. guint addr_cnt, i, port;
  322. gboolean seen_addr, reset_errors = FALSE;
  323. struct upstream_inet_addr_entry *cur, *tmp;
  324. GPtrArray *new_addrs;
  325. struct upstream_addr_elt *addr_elt, *naddr;
  326. /*
  327. * We need first of all get the saved port, since DNS gives us no
  328. * idea about what port has been used previously
  329. */
  330. RSPAMD_UPSTREAM_LOCK (upstream);
  331. if (upstream->addrs.addr->len > 0 && upstream->new_addrs) {
  332. addr_elt = g_ptr_array_index (upstream->addrs.addr, 0);
  333. port = rspamd_inet_address_get_port (addr_elt->addr);
  334. /* Now calculate new addrs count */
  335. addr_cnt = 0;
  336. LL_FOREACH (upstream->new_addrs, cur) {
  337. addr_cnt++;
  338. }
  339. /* At 10% probability reset errors on addr elements */
  340. if (rspamd_random_double_fast () > 0.9) {
  341. reset_errors = TRUE;
  342. msg_debug_upstream ("reset errors on upstream %s",
  343. upstream->name);
  344. }
  345. new_addrs = g_ptr_array_new_full (addr_cnt, rspamd_upstream_addr_elt_dtor);
  346. /* Copy addrs back */
  347. LL_FOREACH (upstream->new_addrs, cur) {
  348. seen_addr = FALSE;
  349. naddr = NULL;
  350. /* Ports are problematic, set to compare in the next block */
  351. rspamd_inet_address_set_port (cur->addr, port);
  352. PTR_ARRAY_FOREACH (upstream->addrs.addr, i, addr_elt) {
  353. if (rspamd_inet_address_compare (addr_elt->addr, cur->addr, FALSE) == 0) {
  354. naddr = g_malloc0 (sizeof (*naddr));
  355. naddr->addr = cur->addr;
  356. naddr->errors = reset_errors ? 0 : addr_elt->errors;
  357. seen_addr = TRUE;
  358. break;
  359. }
  360. }
  361. if (!seen_addr) {
  362. naddr = g_malloc0 (sizeof (*naddr));
  363. naddr->addr = cur->addr;
  364. naddr->errors = 0;
  365. msg_debug_upstream ("new address for %s: %s",
  366. upstream->name,
  367. rspamd_inet_address_to_string_pretty (naddr->addr));
  368. }
  369. else {
  370. msg_debug_upstream ("existing address for %s: %s",
  371. upstream->name,
  372. rspamd_inet_address_to_string_pretty (cur->addr));
  373. }
  374. g_ptr_array_add (new_addrs, naddr);
  375. }
  376. /* Free old addresses */
  377. g_ptr_array_free (upstream->addrs.addr, TRUE);
  378. upstream->addrs.cur = 0;
  379. upstream->addrs.addr = new_addrs;
  380. g_ptr_array_sort (upstream->addrs.addr, rspamd_upstream_addr_sort_func);
  381. }
  382. LL_FOREACH_SAFE (upstream->new_addrs, cur, tmp) {
  383. /* Do not free inet address pointer since it has been transferred to up */
  384. g_free (cur);
  385. }
  386. upstream->new_addrs = NULL;
  387. RSPAMD_UPSTREAM_UNLOCK (upstream);
  388. }
  389. static void
  390. rspamd_upstream_dns_cb (struct rdns_reply *reply, void *arg)
  391. {
  392. struct upstream *up = (struct upstream *)arg;
  393. struct rdns_reply_entry *entry;
  394. struct upstream_inet_addr_entry *up_ent;
  395. if (reply->code == RDNS_RC_NOERROR) {
  396. entry = reply->entries;
  397. RSPAMD_UPSTREAM_LOCK (up);
  398. while (entry) {
  399. if (entry->type == RDNS_REQUEST_A) {
  400. up_ent = g_malloc0 (sizeof (*up_ent));
  401. up_ent->addr = rspamd_inet_address_new (AF_INET,
  402. &entry->content.a.addr);
  403. LL_PREPEND (up->new_addrs, up_ent);
  404. }
  405. else if (entry->type == RDNS_REQUEST_AAAA) {
  406. up_ent = g_malloc0 (sizeof (*up_ent));
  407. up_ent->addr = rspamd_inet_address_new (AF_INET6,
  408. &entry->content.aaa.addr);
  409. LL_PREPEND (up->new_addrs, up_ent);
  410. }
  411. entry = entry->next;
  412. }
  413. RSPAMD_UPSTREAM_UNLOCK (up);
  414. }
  415. up->dns_requests--;
  416. if (up->dns_requests == 0) {
  417. rspamd_upstream_update_addrs (up);
  418. }
  419. REF_RELEASE (up);
  420. }
  421. struct rspamd_upstream_srv_dns_cb {
  422. struct upstream *up;
  423. guint priority;
  424. guint port;
  425. guint requests_inflight;
  426. };
  427. /* Used when we have resolved SRV record and resolved addrs */
  428. static void
  429. rspamd_upstream_dns_srv_phase2_cb (struct rdns_reply *reply, void *arg)
  430. {
  431. struct rspamd_upstream_srv_dns_cb *cbdata =
  432. (struct rspamd_upstream_srv_dns_cb *)arg;
  433. struct upstream *up;
  434. struct rdns_reply_entry *entry;
  435. struct upstream_inet_addr_entry *up_ent;
  436. up = cbdata->up;
  437. if (reply->code == RDNS_RC_NOERROR) {
  438. entry = reply->entries;
  439. RSPAMD_UPSTREAM_LOCK (up);
  440. while (entry) {
  441. if (entry->type == RDNS_REQUEST_A) {
  442. up_ent = g_malloc0 (sizeof (*up_ent));
  443. up_ent->addr = rspamd_inet_address_new (AF_INET,
  444. &entry->content.a.addr);
  445. up_ent->priority = cbdata->priority;
  446. rspamd_inet_address_set_port (up_ent->addr, cbdata->port);
  447. LL_PREPEND (up->new_addrs, up_ent);
  448. }
  449. else if (entry->type == RDNS_REQUEST_AAAA) {
  450. up_ent = g_malloc0 (sizeof (*up_ent));
  451. up_ent->addr = rspamd_inet_address_new (AF_INET6,
  452. &entry->content.aaa.addr);
  453. up_ent->priority = cbdata->priority;
  454. rspamd_inet_address_set_port (up_ent->addr, cbdata->port);
  455. LL_PREPEND (up->new_addrs, up_ent);
  456. }
  457. entry = entry->next;
  458. }
  459. RSPAMD_UPSTREAM_UNLOCK (up);
  460. }
  461. up->dns_requests--;
  462. cbdata->requests_inflight --;
  463. if (cbdata->requests_inflight == 0) {
  464. g_free (cbdata);
  465. }
  466. if (up->dns_requests == 0) {
  467. rspamd_upstream_update_addrs (up);
  468. }
  469. REF_RELEASE (up);
  470. }
  471. static void
  472. rspamd_upstream_dns_srv_cb (struct rdns_reply *reply, void *arg)
  473. {
  474. struct upstream *upstream = (struct upstream *) arg;
  475. struct rdns_reply_entry *entry;
  476. struct rspamd_upstream_srv_dns_cb *ncbdata;
  477. if (reply->code == RDNS_RC_NOERROR) {
  478. entry = reply->entries;
  479. RSPAMD_UPSTREAM_LOCK (upstream);
  480. while (entry) {
  481. /* XXX: we ignore weight as it contradicts with upstreams logic */
  482. if (entry->type == RDNS_REQUEST_SRV) {
  483. msg_debug_upstream ("got srv reply for %s: %s "
  484. "(weight=%d, priority=%d, port=%d)",
  485. upstream->name, entry->content.srv.target,
  486. entry->content.srv.weight, entry->content.srv.priority,
  487. entry->content.srv.port);
  488. ncbdata = g_malloc0 (sizeof (*ncbdata));
  489. ncbdata->priority = entry->content.srv.weight;
  490. ncbdata->port = entry->content.srv.port;
  491. /* XXX: for all entries? */
  492. upstream->ttl = entry->ttl;
  493. if (rdns_make_request_full (upstream->ctx->res,
  494. rspamd_upstream_dns_srv_phase2_cb, ncbdata,
  495. upstream->ls->limits->dns_timeout,
  496. upstream->ls->limits->dns_retransmits,
  497. 1, entry->content.srv.target, RDNS_REQUEST_A) != NULL) {
  498. upstream->dns_requests++;
  499. REF_RETAIN (upstream);
  500. ncbdata->requests_inflight ++;
  501. }
  502. if (rdns_make_request_full (upstream->ctx->res,
  503. rspamd_upstream_dns_srv_phase2_cb, ncbdata,
  504. upstream->ls->limits->dns_timeout,
  505. upstream->ls->limits->dns_retransmits,
  506. 1, entry->content.srv.target, RDNS_REQUEST_AAAA) != NULL) {
  507. upstream->dns_requests++;
  508. REF_RETAIN (upstream);
  509. ncbdata->requests_inflight ++;
  510. }
  511. if (ncbdata->requests_inflight == 0) {
  512. g_free (ncbdata);
  513. }
  514. }
  515. entry = entry->next;
  516. }
  517. RSPAMD_UPSTREAM_UNLOCK (upstream);
  518. }
  519. upstream->dns_requests--;
  520. REF_RELEASE (upstream);
  521. }
  522. static void
  523. rspamd_upstream_revive_cb (struct ev_loop *loop, ev_timer *w, int revents)
  524. {
  525. struct upstream *upstream = (struct upstream *)w->data;
  526. RSPAMD_UPSTREAM_LOCK (upstream);
  527. ev_timer_stop (loop, w);
  528. msg_debug_upstream ("revive upstream %s", upstream->name);
  529. if (upstream->ls) {
  530. rspamd_upstream_set_active (upstream->ls, upstream);
  531. }
  532. RSPAMD_UPSTREAM_UNLOCK (upstream);
  533. g_assert (upstream->ref.refcount > 1);
  534. REF_RELEASE (upstream);
  535. }
  536. static void
  537. rspamd_upstream_resolve_addrs (const struct upstream_list *ls,
  538. struct upstream *upstream)
  539. {
  540. /* XXX: maybe make it configurable */
  541. static const gdouble min_resolve_interval = 60.0;
  542. if (upstream->ctx->res != NULL &&
  543. upstream->ctx->configured &&
  544. upstream->dns_requests == 0 &&
  545. !(upstream->flags & RSPAMD_UPSTREAM_FLAG_NORESOLVE)) {
  546. gdouble now = ev_now (upstream->ctx->event_loop);
  547. if (now - upstream->last_resolve < min_resolve_interval) {
  548. msg_info_upstream ("do not resolve upstream %s as it was checked %.0f "
  549. "seconds ago (%.0f is minimum)",
  550. upstream->name, now - upstream->last_resolve,
  551. min_resolve_interval);
  552. return;
  553. }
  554. /* Resolve name of the upstream one more time */
  555. if (upstream->name[0] != '/') {
  556. upstream->last_resolve = now;
  557. /*
  558. * If upstream name has a port, then we definitely need to resolve
  559. * merely host part!
  560. */
  561. char dns_name[253 + 1]; /* 253 == max dns name + \0 */
  562. const char *semicolon_pos = strchr(upstream->name, ':');
  563. if (semicolon_pos != NULL && semicolon_pos > upstream->name) {
  564. if (sizeof (dns_name) > semicolon_pos - upstream->name) {
  565. rspamd_strlcpy(dns_name, upstream->name,
  566. semicolon_pos - upstream->name + 1);
  567. }
  568. else {
  569. /* XXX: truncated */
  570. msg_err_upstream ("internal error: upstream name is larger than"
  571. "max DNS name: %s", upstream->name);
  572. rspamd_strlcpy(dns_name, upstream->name, sizeof(dns_name));
  573. }
  574. }
  575. else {
  576. rspamd_strlcpy(dns_name, upstream->name, sizeof(dns_name));
  577. }
  578. if (upstream->flags & RSPAMD_UPSTREAM_FLAG_SRV_RESOLVE) {
  579. if (rdns_make_request_full (upstream->ctx->res,
  580. rspamd_upstream_dns_srv_cb, upstream,
  581. ls->limits->dns_timeout, ls->limits->dns_retransmits,
  582. 1, dns_name, RDNS_REQUEST_SRV) != NULL) {
  583. upstream->dns_requests++;
  584. REF_RETAIN (upstream);
  585. }
  586. }
  587. else {
  588. if (rdns_make_request_full (upstream->ctx->res,
  589. rspamd_upstream_dns_cb, upstream,
  590. ls->limits->dns_timeout, ls->limits->dns_retransmits,
  591. 1, dns_name, RDNS_REQUEST_A) != NULL) {
  592. upstream->dns_requests++;
  593. REF_RETAIN (upstream);
  594. }
  595. if (rdns_make_request_full (upstream->ctx->res,
  596. rspamd_upstream_dns_cb, upstream,
  597. ls->limits->dns_timeout, ls->limits->dns_retransmits,
  598. 1, dns_name, RDNS_REQUEST_AAAA) != NULL) {
  599. upstream->dns_requests++;
  600. REF_RETAIN (upstream);
  601. }
  602. }
  603. }
  604. }
  605. else if (upstream->dns_requests != 0) {
  606. msg_info_upstream ("do not resolve upstream %s as another request for "
  607. "resolving has been already issued",
  608. upstream->name);
  609. }
  610. }
  611. static void
  612. rspamd_upstream_lazy_resolve_cb (struct ev_loop *loop, ev_timer *w, int revents)
  613. {
  614. struct upstream *up = (struct upstream *)w->data;
  615. RSPAMD_UPSTREAM_LOCK (up);
  616. ev_timer_stop (loop, w);
  617. if (up->ls) {
  618. rspamd_upstream_resolve_addrs (up->ls, up);
  619. if (up->ttl == 0 || up->ttl > up->ls->limits->lazy_resolve_time) {
  620. w->repeat = rspamd_time_jitter (up->ls->limits->lazy_resolve_time,
  621. up->ls->limits->lazy_resolve_time * .1);
  622. }
  623. else {
  624. w->repeat = up->ttl;
  625. }
  626. ev_timer_again (loop, w);
  627. }
  628. RSPAMD_UPSTREAM_UNLOCK (up);
  629. }
  630. static void
  631. rspamd_upstream_set_inactive (struct upstream_list *ls, struct upstream *upstream)
  632. {
  633. gdouble ntim;
  634. guint i;
  635. struct upstream *cur;
  636. struct upstream_list_watcher *w;
  637. RSPAMD_UPSTREAM_LOCK (ls);
  638. g_ptr_array_remove_index (ls->alive, upstream->active_idx);
  639. upstream->active_idx = -1;
  640. /* We need to update all indices */
  641. for (i = 0; i < ls->alive->len; i ++) {
  642. cur = g_ptr_array_index (ls->alive, i);
  643. cur->active_idx = i;
  644. }
  645. if (upstream->ctx) {
  646. rspamd_upstream_resolve_addrs (ls, upstream);
  647. REF_RETAIN (upstream);
  648. ntim = rspamd_time_jitter (ls->limits->revive_time,
  649. ls->limits->revive_time * ls->limits->revive_jitter);
  650. if (ev_can_stop (&upstream->ev)) {
  651. ev_timer_stop (upstream->ctx->event_loop, &upstream->ev);
  652. }
  653. msg_debug_upstream ("mark upstream %s inactive; revive in %.0f seconds",
  654. upstream->name, ntim);
  655. ev_timer_init (&upstream->ev, rspamd_upstream_revive_cb, ntim, 0);
  656. upstream->ev.data = upstream;
  657. if (upstream->ctx->event_loop != NULL && upstream->ctx->configured) {
  658. ev_timer_start (upstream->ctx->event_loop, &upstream->ev);
  659. }
  660. }
  661. DL_FOREACH (upstream->ls->watchers, w) {
  662. if (w->events_mask & RSPAMD_UPSTREAM_WATCH_OFFLINE) {
  663. w->func (upstream, RSPAMD_UPSTREAM_WATCH_OFFLINE, upstream->errors, w->ud);
  664. }
  665. }
  666. RSPAMD_UPSTREAM_UNLOCK (ls);
  667. }
  668. void
  669. rspamd_upstream_fail (struct upstream *upstream,
  670. gboolean addr_failure,
  671. const gchar *reason)
  672. {
  673. gdouble error_rate = 0, max_error_rate = 0;
  674. gdouble sec_last, sec_cur;
  675. struct upstream_addr_elt *addr_elt;
  676. struct upstream_list_watcher *w;
  677. msg_debug_upstream ("upstream %s failed; reason: %s",
  678. upstream->name,
  679. reason);
  680. if (upstream->ctx && upstream->active_idx != -1 && upstream->ls) {
  681. sec_cur = rspamd_get_ticks (FALSE);
  682. RSPAMD_UPSTREAM_LOCK (upstream);
  683. if (upstream->errors == 0) {
  684. /* We have the first error */
  685. upstream->last_fail = sec_cur;
  686. upstream->errors = 1;
  687. if (upstream->ls && upstream->dns_requests == 0) {
  688. /* Try to re-resolve address immediately */
  689. rspamd_upstream_resolve_addrs (upstream->ls, upstream);
  690. }
  691. DL_FOREACH (upstream->ls->watchers, w) {
  692. if (w->events_mask & RSPAMD_UPSTREAM_WATCH_FAILURE) {
  693. w->func (upstream, RSPAMD_UPSTREAM_WATCH_FAILURE, 1, w->ud);
  694. }
  695. }
  696. }
  697. else {
  698. sec_last = upstream->last_fail;
  699. if (sec_cur >= sec_last) {
  700. upstream->errors ++;
  701. DL_FOREACH (upstream->ls->watchers, w) {
  702. if (w->events_mask & RSPAMD_UPSTREAM_WATCH_FAILURE) {
  703. w->func (upstream, RSPAMD_UPSTREAM_WATCH_FAILURE,
  704. upstream->errors, w->ud);
  705. }
  706. }
  707. if (sec_cur - sec_last >= upstream->ls->limits->error_time) {
  708. error_rate = ((gdouble)upstream->errors) / (sec_cur - sec_last);
  709. max_error_rate = ((gdouble)upstream->ls->limits->max_errors) /
  710. upstream->ls->limits->error_time;
  711. }
  712. if (error_rate > max_error_rate) {
  713. /* Remove upstream from the active list */
  714. if (upstream->ls->ups->len > 1) {
  715. msg_debug_upstream ("mark upstream %s inactive; "
  716. "reason: %s; %.2f "
  717. "error rate (%d errors), "
  718. "%.2f max error rate, "
  719. "%.1f first error time, "
  720. "%.1f current ts, "
  721. "%d upstreams left",
  722. upstream->name,
  723. reason,
  724. error_rate,
  725. upstream->errors,
  726. max_error_rate,
  727. sec_last,
  728. sec_cur,
  729. upstream->ls->alive->len - 1);
  730. rspamd_upstream_set_inactive (upstream->ls, upstream);
  731. upstream->errors = 0;
  732. }
  733. else {
  734. msg_debug_upstream ("cannot mark last alive upstream %s "
  735. "inactive; reason: %s; %.2f "
  736. "error rate (%d errors), "
  737. "%.2f max error rate, "
  738. "%.1f first error time, "
  739. "%.1f current ts",
  740. upstream->name,
  741. reason,
  742. error_rate,
  743. upstream->errors,
  744. max_error_rate,
  745. sec_last,
  746. sec_cur);
  747. /* Just re-resolve addresses */
  748. if (sec_cur - sec_last > upstream->ls->limits->revive_time) {
  749. upstream->errors = 0;
  750. rspamd_upstream_resolve_addrs (upstream->ls, upstream);
  751. }
  752. }
  753. }
  754. else if (sec_cur - sec_last >= upstream->ls->limits->error_time) {
  755. /* Forget the whole interval */
  756. upstream->last_fail = sec_cur;
  757. upstream->errors = 1;
  758. }
  759. }
  760. }
  761. if (addr_failure) {
  762. /* Also increase count of errors for this specific address */
  763. if (upstream->addrs.addr) {
  764. addr_elt = g_ptr_array_index (upstream->addrs.addr,
  765. upstream->addrs.cur);
  766. addr_elt->errors++;
  767. }
  768. }
  769. RSPAMD_UPSTREAM_UNLOCK (upstream);
  770. }
  771. }
  772. void
  773. rspamd_upstream_ok (struct upstream *upstream)
  774. {
  775. struct upstream_addr_elt *addr_elt;
  776. struct upstream_list_watcher *w;
  777. RSPAMD_UPSTREAM_LOCK (upstream);
  778. if (upstream->errors > 0 && upstream->active_idx != -1 && upstream->ls) {
  779. /* We touch upstream if and only if it is active */
  780. msg_debug_upstream ("reset errors on upstream %s (was %ud)", upstream->name, upstream->errors);
  781. upstream->errors = 0;
  782. if (upstream->addrs.addr) {
  783. addr_elt = g_ptr_array_index (upstream->addrs.addr, upstream->addrs.cur);
  784. addr_elt->errors = 0;
  785. }
  786. DL_FOREACH (upstream->ls->watchers, w) {
  787. if (w->events_mask & RSPAMD_UPSTREAM_WATCH_SUCCESS) {
  788. w->func (upstream, RSPAMD_UPSTREAM_WATCH_SUCCESS, 0, w->ud);
  789. }
  790. }
  791. }
  792. RSPAMD_UPSTREAM_UNLOCK (upstream);
  793. }
  794. void
  795. rspamd_upstream_set_weight (struct upstream *up, guint weight)
  796. {
  797. RSPAMD_UPSTREAM_LOCK (up);
  798. up->weight = weight;
  799. RSPAMD_UPSTREAM_UNLOCK (up);
  800. }
  801. #define SEED_CONSTANT 0xa574de7df64e9b9dULL
  802. struct upstream_list*
  803. rspamd_upstreams_create (struct upstream_ctx *ctx)
  804. {
  805. struct upstream_list *ls;
  806. ls = g_malloc0 (sizeof (*ls));
  807. ls->hash_seed = SEED_CONSTANT;
  808. ls->ups = g_ptr_array_new ();
  809. ls->alive = g_ptr_array_new ();
  810. #ifdef UPSTREAMS_THREAD_SAFE
  811. ls->lock = rspamd_mutex_new ();
  812. #endif
  813. ls->cur_elt = 0;
  814. ls->ctx = ctx;
  815. ls->rot_alg = RSPAMD_UPSTREAM_UNDEF;
  816. if (ctx) {
  817. ls->limits = &ctx->limits;
  818. }
  819. else {
  820. ls->limits = &default_limits;
  821. }
  822. return ls;
  823. }
  824. gsize
  825. rspamd_upstreams_count (struct upstream_list *ups)
  826. {
  827. return ups != NULL ? ups->ups->len : 0;
  828. }
  829. gsize
  830. rspamd_upstreams_alive (struct upstream_list *ups)
  831. {
  832. return ups != NULL ? ups->alive->len : 0;
  833. }
  834. static void
  835. rspamd_upstream_dtor (struct upstream *up)
  836. {
  837. struct upstream_inet_addr_entry *cur, *tmp;
  838. if (up->new_addrs) {
  839. LL_FOREACH_SAFE(up->new_addrs, cur, tmp) {
  840. /* Here we need to free pointer as well */
  841. rspamd_inet_address_free (cur->addr);
  842. g_free (cur);
  843. }
  844. }
  845. if (up->addrs.addr) {
  846. g_ptr_array_free (up->addrs.addr, TRUE);
  847. }
  848. #ifdef UPSTREAMS_THREAD_SAFE
  849. rspamd_mutex_free (up->lock);
  850. #endif
  851. if (up->ctx) {
  852. if (ev_can_stop (&up->ev)) {
  853. ev_timer_stop (up->ctx->event_loop, &up->ev);
  854. }
  855. g_queue_delete_link (up->ctx->upstreams, up->ctx_pos);
  856. REF_RELEASE (up->ctx);
  857. }
  858. g_free (up);
  859. }
  860. rspamd_inet_addr_t*
  861. rspamd_upstream_addr_next (struct upstream *up)
  862. {
  863. guint idx, next_idx;
  864. struct upstream_addr_elt *e1, *e2;
  865. do {
  866. idx = up->addrs.cur;
  867. next_idx = (idx + 1) % up->addrs.addr->len;
  868. e1 = g_ptr_array_index (up->addrs.addr, idx);
  869. e2 = g_ptr_array_index (up->addrs.addr, next_idx);
  870. up->addrs.cur = next_idx;
  871. } while (e2->errors > e1->errors);
  872. return e2->addr;
  873. }
  874. rspamd_inet_addr_t*
  875. rspamd_upstream_addr_cur (const struct upstream *up)
  876. {
  877. struct upstream_addr_elt *elt;
  878. elt = g_ptr_array_index (up->addrs.addr, up->addrs.cur);
  879. return elt->addr;
  880. }
  881. const gchar*
  882. rspamd_upstream_name (struct upstream *up)
  883. {
  884. return up->name;
  885. }
  886. gint
  887. rspamd_upstream_port (struct upstream *up)
  888. {
  889. struct upstream_addr_elt *elt;
  890. elt = g_ptr_array_index (up->addrs.addr, up->addrs.cur);
  891. return rspamd_inet_address_get_port (elt->addr);
  892. }
  893. gboolean
  894. rspamd_upstreams_add_upstream (struct upstream_list *ups, const gchar *str,
  895. guint16 def_port, enum rspamd_upstream_parse_type parse_type,
  896. void *data)
  897. {
  898. struct upstream *upstream;
  899. GPtrArray *addrs = NULL;
  900. guint i, slen;
  901. rspamd_inet_addr_t *addr;
  902. enum rspamd_parse_host_port_result ret = RSPAMD_PARSE_ADDR_FAIL;
  903. upstream = g_malloc0 (sizeof (*upstream));
  904. slen = strlen (str);
  905. switch (parse_type) {
  906. case RSPAMD_UPSTREAM_PARSE_DEFAULT:
  907. if (slen > sizeof ("service=") &&
  908. RSPAMD_LEN_CHECK_STARTS_WITH (str, slen, "service=")) {
  909. const gchar *plus_pos, *service_pos, *semicolon_pos;
  910. /* Accept service=srv_name+hostname[:priority] */
  911. service_pos = str + sizeof ("service=") - 1;
  912. plus_pos = strchr (service_pos, '+');
  913. if (plus_pos != NULL) {
  914. semicolon_pos = strchr (plus_pos + 1, ':');
  915. if (semicolon_pos) {
  916. upstream->weight = strtoul (semicolon_pos + 1, NULL, 10);
  917. }
  918. else {
  919. semicolon_pos = plus_pos + strlen (plus_pos);
  920. }
  921. /*
  922. * Now our name is _service._tcp.<domain>
  923. * where <domain> is string between semicolon_pos and plus_pos +1
  924. * while service is a string between service_pos and plus_pos
  925. */
  926. guint namelen = (semicolon_pos - (plus_pos + 1)) +
  927. (plus_pos - service_pos) +
  928. (sizeof ("tcp") - 1) +
  929. 4;
  930. addrs = g_ptr_array_sized_new (1);
  931. upstream->name = ups->ctx ?
  932. rspamd_mempool_alloc (ups->ctx->pool, namelen + 1) :
  933. g_malloc (namelen + 1);
  934. rspamd_snprintf (upstream->name, namelen + 1,
  935. "_%*s._tcp.%*s",
  936. (gint)(plus_pos - service_pos), service_pos,
  937. (gint)(semicolon_pos - (plus_pos + 1)), plus_pos + 1);
  938. upstream->flags |= RSPAMD_UPSTREAM_FLAG_SRV_RESOLVE;
  939. ret = RSPAMD_PARSE_ADDR_RESOLVED;
  940. }
  941. }
  942. else {
  943. ret = rspamd_parse_host_port_priority (str, &addrs,
  944. &upstream->weight,
  945. &upstream->name, def_port,
  946. FALSE,
  947. ups->ctx ? ups->ctx->pool : NULL);
  948. }
  949. break;
  950. case RSPAMD_UPSTREAM_PARSE_NAMESERVER:
  951. addrs = g_ptr_array_sized_new (1);
  952. if (rspamd_parse_inet_address (&addr, str, strlen (str),
  953. RSPAMD_INET_ADDRESS_PARSE_DEFAULT)) {
  954. if (ups->ctx) {
  955. upstream->name = rspamd_mempool_strdup (ups->ctx->pool, str);
  956. }
  957. else {
  958. upstream->name = g_strdup (str);
  959. }
  960. if (rspamd_inet_address_get_port (addr) == 0) {
  961. rspamd_inet_address_set_port (addr, def_port);
  962. }
  963. g_ptr_array_add (addrs, addr);
  964. ret = RSPAMD_PARSE_ADDR_NUMERIC;
  965. if (ups->ctx) {
  966. rspamd_mempool_add_destructor (ups->ctx->pool,
  967. (rspamd_mempool_destruct_t) rspamd_inet_address_free,
  968. addr);
  969. rspamd_mempool_add_destructor (ups->ctx->pool,
  970. (rspamd_mempool_destruct_t) rspamd_ptr_array_free_hard,
  971. addrs);
  972. }
  973. }
  974. else {
  975. g_ptr_array_free (addrs, TRUE);
  976. }
  977. break;
  978. }
  979. if (ret == RSPAMD_PARSE_ADDR_FAIL) {
  980. g_free (upstream);
  981. return FALSE;
  982. }
  983. else {
  984. upstream->flags |= ups->flags;
  985. if (ret == RSPAMD_PARSE_ADDR_NUMERIC) {
  986. /* Add noresolve flag */
  987. upstream->flags |= RSPAMD_UPSTREAM_FLAG_NORESOLVE;
  988. }
  989. for (i = 0; i < addrs->len; i ++) {
  990. addr = g_ptr_array_index (addrs, i);
  991. rspamd_upstream_add_addr (upstream, rspamd_inet_address_copy (addr));
  992. }
  993. }
  994. if (upstream->weight == 0 && ups->rot_alg == RSPAMD_UPSTREAM_MASTER_SLAVE) {
  995. /* Special heuristic for master-slave rotation */
  996. if (ups->ups->len == 0) {
  997. /* Prioritize the first */
  998. upstream->weight = 1;
  999. }
  1000. }
  1001. g_ptr_array_add (ups->ups, upstream);
  1002. upstream->ud = data;
  1003. upstream->cur_weight = upstream->weight;
  1004. upstream->ls = ups;
  1005. REF_INIT_RETAIN (upstream, rspamd_upstream_dtor);
  1006. #ifdef UPSTREAMS_THREAD_SAFE
  1007. upstream->lock = rspamd_mutex_new ();
  1008. #endif
  1009. upstream->ctx = ups->ctx;
  1010. if (upstream->ctx) {
  1011. REF_RETAIN (ups->ctx);
  1012. g_queue_push_tail (ups->ctx->upstreams, upstream);
  1013. upstream->ctx_pos = g_queue_peek_tail_link (ups->ctx->upstreams);
  1014. }
  1015. guint h = rspamd_cryptobox_fast_hash (upstream->name,
  1016. strlen (upstream->name), 0);
  1017. memset (upstream->uid, 0, sizeof (upstream->uid));
  1018. rspamd_encode_base32_buf ((const guchar *) &h, sizeof (h),
  1019. upstream->uid, sizeof (upstream->uid) - 1, RSPAMD_BASE32_DEFAULT);
  1020. msg_debug_upstream ("added upstream %s (%s)", upstream->name,
  1021. upstream->flags & RSPAMD_UPSTREAM_FLAG_NORESOLVE ? "numeric ip" : "DNS name");
  1022. g_ptr_array_sort (upstream->addrs.addr, rspamd_upstream_addr_sort_func);
  1023. rspamd_upstream_set_active (ups, upstream);
  1024. return TRUE;
  1025. }
  1026. void
  1027. rspamd_upstreams_set_flags (struct upstream_list *ups,
  1028. enum rspamd_upstream_flag flags)
  1029. {
  1030. ups->flags = flags;
  1031. }
  1032. void
  1033. rspamd_upstreams_set_rotation (struct upstream_list *ups,
  1034. enum rspamd_upstream_rotation rot)
  1035. {
  1036. ups->rot_alg = rot;
  1037. }
  1038. gboolean
  1039. rspamd_upstream_add_addr (struct upstream *up, rspamd_inet_addr_t *addr)
  1040. {
  1041. struct upstream_addr_elt *elt;
  1042. /*
  1043. * XXX: slow and inefficient
  1044. */
  1045. if (up->addrs.addr == NULL) {
  1046. up->addrs.addr = g_ptr_array_new_full (8, rspamd_upstream_addr_elt_dtor);
  1047. }
  1048. elt = g_malloc0 (sizeof (*elt));
  1049. elt->addr = addr;
  1050. g_ptr_array_add (up->addrs.addr, elt);
  1051. g_ptr_array_sort (up->addrs.addr, rspamd_upstream_addr_sort_func);
  1052. return TRUE;
  1053. }
  1054. gboolean
  1055. rspamd_upstreams_parse_line_len (struct upstream_list *ups,
  1056. const gchar *str, gsize len, guint16 def_port, void *data)
  1057. {
  1058. const gchar *end = str + len, *p = str;
  1059. const gchar *separators = ";, \n\r\t";
  1060. gchar *tmp;
  1061. guint span_len;
  1062. gboolean ret = FALSE;
  1063. if (RSPAMD_LEN_CHECK_STARTS_WITH(p, len, "random:")) {
  1064. ups->rot_alg = RSPAMD_UPSTREAM_RANDOM;
  1065. p += sizeof ("random:") - 1;
  1066. }
  1067. else if (RSPAMD_LEN_CHECK_STARTS_WITH(p, len, "master-slave:")) {
  1068. ups->rot_alg = RSPAMD_UPSTREAM_MASTER_SLAVE;
  1069. p += sizeof ("master-slave:") - 1;
  1070. }
  1071. else if (RSPAMD_LEN_CHECK_STARTS_WITH(p, len, "round-robin:")) {
  1072. ups->rot_alg = RSPAMD_UPSTREAM_ROUND_ROBIN;
  1073. p += sizeof ("round-robin:") - 1;
  1074. }
  1075. else if (RSPAMD_LEN_CHECK_STARTS_WITH(p, len, "hash:")) {
  1076. ups->rot_alg = RSPAMD_UPSTREAM_HASHED;
  1077. p += sizeof ("hash:") - 1;
  1078. }
  1079. while (p < end) {
  1080. span_len = rspamd_memcspn (p, separators, end - p);
  1081. if (span_len > 0) {
  1082. tmp = g_malloc (span_len + 1);
  1083. rspamd_strlcpy (tmp, p, span_len + 1);
  1084. if (rspamd_upstreams_add_upstream (ups, tmp, def_port,
  1085. RSPAMD_UPSTREAM_PARSE_DEFAULT,
  1086. data)) {
  1087. ret = TRUE;
  1088. }
  1089. g_free (tmp);
  1090. }
  1091. p += span_len;
  1092. /* Skip separators */
  1093. if (p < end) {
  1094. p += rspamd_memspn (p, separators, end - p);
  1095. }
  1096. }
  1097. if (!ups->ups_line) {
  1098. ups->ups_line = g_malloc (len + 1);
  1099. rspamd_strlcpy (ups->ups_line, str, len + 1);
  1100. }
  1101. return ret;
  1102. }
  1103. gboolean
  1104. rspamd_upstreams_parse_line (struct upstream_list *ups,
  1105. const gchar *str, guint16 def_port, void *data)
  1106. {
  1107. return rspamd_upstreams_parse_line_len (ups, str, strlen (str),
  1108. def_port, data);
  1109. }
  1110. gboolean
  1111. rspamd_upstreams_from_ucl (struct upstream_list *ups,
  1112. const ucl_object_t *in, guint16 def_port, void *data)
  1113. {
  1114. gboolean ret = FALSE;
  1115. const ucl_object_t *cur;
  1116. ucl_object_iter_t it = NULL;
  1117. it = ucl_object_iterate_new (in);
  1118. while ((cur = ucl_object_iterate_safe (it, true)) != NULL) {
  1119. if (ucl_object_type (cur) == UCL_STRING) {
  1120. ret = rspamd_upstreams_parse_line (ups, ucl_object_tostring (cur),
  1121. def_port, data);
  1122. }
  1123. }
  1124. ucl_object_iterate_free (it);
  1125. return ret;
  1126. }
  1127. void
  1128. rspamd_upstreams_destroy (struct upstream_list *ups)
  1129. {
  1130. guint i;
  1131. struct upstream *up;
  1132. struct upstream_list_watcher *w, *tmp;
  1133. if (ups != NULL) {
  1134. g_ptr_array_free (ups->alive, TRUE);
  1135. for (i = 0; i < ups->ups->len; i ++) {
  1136. up = g_ptr_array_index (ups->ups, i);
  1137. up->ls = NULL;
  1138. REF_RELEASE (up);
  1139. }
  1140. DL_FOREACH_SAFE (ups->watchers, w, tmp) {
  1141. if (w->dtor) {
  1142. w->dtor (w->ud);
  1143. }
  1144. g_free (w);
  1145. }
  1146. g_free (ups->ups_line);
  1147. g_ptr_array_free (ups->ups, TRUE);
  1148. #ifdef UPSTREAMS_THREAD_SAFE
  1149. rspamd_mutex_free (ups->lock);
  1150. #endif
  1151. g_free (ups);
  1152. }
  1153. }
  1154. static void
  1155. rspamd_upstream_restore_cb (gpointer elt, gpointer ls)
  1156. {
  1157. struct upstream *up = (struct upstream *)elt;
  1158. struct upstream_list *ups = (struct upstream_list *)ls;
  1159. struct upstream_list_watcher *w;
  1160. /* Here the upstreams list is already locked */
  1161. RSPAMD_UPSTREAM_LOCK (up);
  1162. if (ev_can_stop (&up->ev)) {
  1163. ev_timer_stop (up->ctx->event_loop, &up->ev);
  1164. }
  1165. g_ptr_array_add (ups->alive, up);
  1166. up->active_idx = ups->alive->len - 1;
  1167. RSPAMD_UPSTREAM_UNLOCK (up);
  1168. DL_FOREACH (up->ls->watchers, w) {
  1169. if (w->events_mask & RSPAMD_UPSTREAM_WATCH_ONLINE) {
  1170. w->func (up, RSPAMD_UPSTREAM_WATCH_ONLINE, up->errors, w->ud);
  1171. }
  1172. }
  1173. /* For revive event */
  1174. g_assert (up->ref.refcount > 1);
  1175. REF_RELEASE (up);
  1176. }
  1177. static struct upstream*
  1178. rspamd_upstream_get_random (struct upstream_list *ups,
  1179. struct upstream *except)
  1180. {
  1181. for (;;) {
  1182. guint idx = ottery_rand_range (ups->alive->len - 1);
  1183. struct upstream *up;
  1184. up = g_ptr_array_index (ups->alive, idx);
  1185. if (except && up == except) {
  1186. continue;
  1187. }
  1188. return up;
  1189. }
  1190. }
  1191. static struct upstream*
  1192. rspamd_upstream_get_round_robin (struct upstream_list *ups,
  1193. struct upstream *except,
  1194. gboolean use_cur)
  1195. {
  1196. guint max_weight = 0, min_checked = G_MAXUINT;
  1197. struct upstream *up = NULL, *selected = NULL, *min_checked_sel = NULL;
  1198. guint i;
  1199. /* Select upstream with the maximum cur_weight */
  1200. RSPAMD_UPSTREAM_LOCK (ups);
  1201. for (i = 0; i < ups->alive->len; i ++) {
  1202. up = g_ptr_array_index (ups->alive, i);
  1203. if (except != NULL && up == except) {
  1204. continue;
  1205. }
  1206. if (use_cur) {
  1207. if (up->cur_weight > max_weight) {
  1208. selected = up;
  1209. max_weight = up->cur_weight;
  1210. }
  1211. }
  1212. else {
  1213. if (up->weight > max_weight) {
  1214. selected = up;
  1215. max_weight = up->weight;
  1216. }
  1217. }
  1218. /*
  1219. * This code is used when all upstreams have zero weight
  1220. * The logic is to select least currently used upstream and penalise
  1221. * upstream with errors. The error penalty should no be too high
  1222. * to avoid sudden traffic drop in this case.
  1223. */
  1224. if (up->checked + up->errors * 2 < min_checked) {
  1225. min_checked_sel = up;
  1226. min_checked = up->checked;
  1227. }
  1228. }
  1229. if (max_weight == 0) {
  1230. /* All upstreams have zero weight */
  1231. if (min_checked > G_MAXUINT / 2) {
  1232. /* Reset all checked counters to avoid overflow */
  1233. for (i = 0; i < ups->alive->len; i ++) {
  1234. up = g_ptr_array_index (ups->alive, i);
  1235. up->checked = 0;
  1236. }
  1237. }
  1238. selected = min_checked_sel;
  1239. }
  1240. if (use_cur && selected) {
  1241. if (selected->cur_weight > 0) {
  1242. selected->cur_weight--;
  1243. }
  1244. else {
  1245. selected->cur_weight = selected->weight;
  1246. }
  1247. }
  1248. RSPAMD_UPSTREAM_UNLOCK (ups);
  1249. return selected;
  1250. }
  1251. /*
  1252. * The key idea of this function is obtained from the following paper:
  1253. * A Fast, Minimal Memory, Consistent Hash Algorithm
  1254. * John Lamping, Eric Veach
  1255. *
  1256. * http://arxiv.org/abs/1406.2294
  1257. */
  1258. static guint32
  1259. rspamd_consistent_hash (guint64 key, guint32 nbuckets)
  1260. {
  1261. gint64 b = -1, j = 0;
  1262. while (j < nbuckets) {
  1263. b = j;
  1264. key *= 2862933555777941757ULL + 1;
  1265. j = (b + 1) * (double)(1ULL << 31) / (double)((key >> 33) + 1ULL);
  1266. }
  1267. return b;
  1268. }
  1269. static struct upstream*
  1270. rspamd_upstream_get_hashed (struct upstream_list *ups,
  1271. struct upstream *except,
  1272. const guint8 *key, guint keylen)
  1273. {
  1274. guint64 k;
  1275. guint32 idx;
  1276. static const guint max_tries = 20;
  1277. struct upstream *up = NULL;
  1278. /* Generate 64 bits input key */
  1279. k = rspamd_cryptobox_fast_hash_specific (RSPAMD_CRYPTOBOX_XXHASH64,
  1280. key, keylen, ups->hash_seed);
  1281. RSPAMD_UPSTREAM_LOCK (ups);
  1282. /*
  1283. * Select new upstream from all upstreams
  1284. */
  1285. for (guint i = 0; i < max_tries; i ++) {
  1286. idx = rspamd_consistent_hash (k, ups->ups->len);
  1287. up = g_ptr_array_index (ups->ups, idx);
  1288. if (up->active_idx < 0 || (except != NULL && up == except)) {
  1289. /* Found inactive or excluded upstream */
  1290. k = mum_hash_step (k, ups->hash_seed);
  1291. }
  1292. else {
  1293. break;
  1294. }
  1295. }
  1296. RSPAMD_UPSTREAM_UNLOCK (ups);
  1297. if (up->active_idx >= 0) {
  1298. return up;
  1299. }
  1300. /* We failed to find any active upstream */
  1301. up = rspamd_upstream_get_random (ups, except);
  1302. msg_info ("failed to find hashed upstream for %s, fallback to random: %s",
  1303. ups->ups_line, up->name);
  1304. return up;
  1305. }
  1306. static struct upstream*
  1307. rspamd_upstream_get_common (struct upstream_list *ups,
  1308. struct upstream* except,
  1309. enum rspamd_upstream_rotation default_type,
  1310. const guchar *key, gsize keylen,
  1311. gboolean forced)
  1312. {
  1313. enum rspamd_upstream_rotation type;
  1314. struct upstream *up = NULL;
  1315. RSPAMD_UPSTREAM_LOCK (ups);
  1316. if (ups->alive->len == 0) {
  1317. /* We have no upstreams alive */
  1318. msg_warn ("there are no alive upstreams left for %s, revive all of them",
  1319. ups->ups_line);
  1320. g_ptr_array_foreach (ups->ups, rspamd_upstream_restore_cb, ups);
  1321. }
  1322. RSPAMD_UPSTREAM_UNLOCK (ups);
  1323. if (ups->alive->len == 1 && default_type != RSPAMD_UPSTREAM_SEQUENTIAL) {
  1324. /* Fast path */
  1325. up = g_ptr_array_index (ups->alive, 0);
  1326. goto end;
  1327. }
  1328. if (!forced) {
  1329. type = ups->rot_alg != RSPAMD_UPSTREAM_UNDEF ? ups->rot_alg : default_type;
  1330. }
  1331. else {
  1332. type = default_type != RSPAMD_UPSTREAM_UNDEF ? default_type : ups->rot_alg;
  1333. }
  1334. if (type == RSPAMD_UPSTREAM_HASHED && (keylen == 0 || key == NULL)) {
  1335. /* Cannot use hashed rotation when no key is specified, switch to random */
  1336. type = RSPAMD_UPSTREAM_RANDOM;
  1337. }
  1338. switch (type) {
  1339. default:
  1340. case RSPAMD_UPSTREAM_RANDOM:
  1341. up = rspamd_upstream_get_random (ups, except);
  1342. break;
  1343. case RSPAMD_UPSTREAM_HASHED:
  1344. up = rspamd_upstream_get_hashed (ups, except, key, keylen);
  1345. break;
  1346. case RSPAMD_UPSTREAM_ROUND_ROBIN:
  1347. up = rspamd_upstream_get_round_robin (ups, except, TRUE);
  1348. break;
  1349. case RSPAMD_UPSTREAM_MASTER_SLAVE:
  1350. up = rspamd_upstream_get_round_robin (ups, except, FALSE);
  1351. break;
  1352. case RSPAMD_UPSTREAM_SEQUENTIAL:
  1353. if (ups->cur_elt >= ups->alive->len) {
  1354. ups->cur_elt = 0;
  1355. return NULL;
  1356. }
  1357. up = g_ptr_array_index (ups->alive, ups->cur_elt ++);
  1358. break;
  1359. }
  1360. end:
  1361. if (up) {
  1362. up->checked ++;
  1363. }
  1364. return up;
  1365. }
  1366. struct upstream*
  1367. rspamd_upstream_get (struct upstream_list *ups,
  1368. enum rspamd_upstream_rotation default_type,
  1369. const guchar *key, gsize keylen)
  1370. {
  1371. return rspamd_upstream_get_common (ups, NULL, default_type, key, keylen, FALSE);
  1372. }
  1373. struct upstream*
  1374. rspamd_upstream_get_forced (struct upstream_list *ups,
  1375. enum rspamd_upstream_rotation forced_type,
  1376. const guchar *key, gsize keylen)
  1377. {
  1378. return rspamd_upstream_get_common (ups, NULL, forced_type, key, keylen, TRUE);
  1379. }
  1380. struct upstream *rspamd_upstream_get_except (struct upstream_list *ups,
  1381. struct upstream *except,
  1382. enum rspamd_upstream_rotation default_type,
  1383. const guchar *key, gsize keylen)
  1384. {
  1385. return rspamd_upstream_get_common (ups, except, default_type, key, keylen, FALSE);
  1386. }
  1387. void
  1388. rspamd_upstream_reresolve (struct upstream_ctx *ctx)
  1389. {
  1390. GList *cur;
  1391. struct upstream *up;
  1392. cur = ctx->upstreams->head;
  1393. while (cur) {
  1394. up = cur->data;
  1395. REF_RETAIN (up);
  1396. rspamd_upstream_resolve_addrs (up->ls, up);
  1397. REF_RELEASE (up);
  1398. cur = g_list_next (cur);
  1399. }
  1400. }
  1401. gpointer
  1402. rspamd_upstream_set_data (struct upstream *up, gpointer data)
  1403. {
  1404. gpointer prev_data = up->data;
  1405. up->data = data;
  1406. return prev_data;
  1407. }
  1408. gpointer
  1409. rspamd_upstream_get_data (struct upstream *up)
  1410. {
  1411. return up->data;
  1412. }
  1413. void
  1414. rspamd_upstreams_foreach (struct upstream_list *ups,
  1415. rspamd_upstream_traverse_func cb, void *ud)
  1416. {
  1417. struct upstream *up;
  1418. guint i;
  1419. for (i = 0; i < ups->ups->len; i ++) {
  1420. up = g_ptr_array_index (ups->ups, i);
  1421. cb (up, i, ud);
  1422. }
  1423. }
  1424. void
  1425. rspamd_upstreams_set_limits (struct upstream_list *ups,
  1426. gdouble revive_time,
  1427. gdouble revive_jitter,
  1428. gdouble error_time,
  1429. gdouble dns_timeout,
  1430. guint max_errors,
  1431. guint dns_retransmits)
  1432. {
  1433. struct upstream_limits *nlimits;
  1434. g_assert (ups != NULL);
  1435. nlimits = rspamd_mempool_alloc (ups->ctx->pool, sizeof (*nlimits));
  1436. memcpy (nlimits, ups->limits, sizeof (*nlimits));
  1437. if (!isnan (revive_time)) {
  1438. nlimits->revive_time = revive_time;
  1439. }
  1440. if (!isnan (revive_jitter)) {
  1441. nlimits->revive_jitter = revive_jitter;
  1442. }
  1443. if (!isnan (error_time)) {
  1444. nlimits->error_time = error_time;
  1445. }
  1446. if (!isnan (dns_timeout)) {
  1447. nlimits->dns_timeout = dns_timeout;
  1448. }
  1449. if (max_errors > 0) {
  1450. nlimits->max_errors = max_errors;
  1451. }
  1452. if (dns_retransmits > 0) {
  1453. nlimits->dns_retransmits = dns_retransmits;
  1454. }
  1455. ups->limits = nlimits;
  1456. }
  1457. void rspamd_upstreams_add_watch_callback (struct upstream_list *ups,
  1458. enum rspamd_upstreams_watch_event events,
  1459. rspamd_upstream_watch_func func,
  1460. GFreeFunc dtor,
  1461. gpointer ud)
  1462. {
  1463. struct upstream_list_watcher *nw;
  1464. g_assert ((events & RSPAMD_UPSTREAM_WATCH_ALL) != 0);
  1465. nw = g_malloc (sizeof (*nw));
  1466. nw->func = func;
  1467. nw->events_mask = events;
  1468. nw->ud = ud;
  1469. nw->dtor = dtor;
  1470. DL_APPEND (ups->watchers, nw);
  1471. }
  1472. struct upstream*
  1473. rspamd_upstream_ref (struct upstream *up)
  1474. {
  1475. REF_RETAIN (up);
  1476. return up;
  1477. }
  1478. void
  1479. rspamd_upstream_unref (struct upstream *up)
  1480. {
  1481. REF_RELEASE (up);
  1482. }